-
2010-06-15
iPhone
割肉卖血!
穷追米井誓不罢休!
大家好,最为一个中产阶级二代。
革命道路任重而道远,途中不乏波折。
这些波折中不乏让人困顿迷失,再奋起努力者。
这些波折中的困顿迷失不伐有让我伤害米井者。
同时不得不承认,伤害米井的是我,小米井从小到大就一直受我这个男人的伤害。
但是小米井同学一定要记住。
我可能... -
2010-03-07
月黑风高
夜深人静了。。。。。。音乐还是放着,老婆睡去了。我想说点什么?
最近越来越觉得米井就是了,没错了,还能再有什么呢?上帝啊,如果你存在?我本性不坏,如果你是善良的,你也应该爱善良的人,容易满足的人。不是吗?坏事我不做了,或者我不再追求了,因为如果要娶她,那就没有必要了。虽然沉思录说不要期待未来。我长久以来也坚信未来不可知,但不必因此就要抓住每一次机会,因为这次看到你的背影我惊醒了,我把你抱得更紧了。
还有什么呢?如果环境要降下灾难,谁也逃不掉,但不必... -
2010-02-01
我决定
从明天开始
做俯卧撑。。。。长胸肌
做仰卧起坐。。。。减肚子
弹吉他。。。。泡宝宝
写代码。。。。养宝宝
注意:是从明天开始。。。。。。因为还在给代码理清思路。。。。。
-
2009-09-30
踏出一步
踏出第一步后,世界动了起来
曾经无数次狼人站在十字路口,认为走出去的那条路是很重要的选择。他走着走着,就长大了。
现在的狼人,走过十字路口,认为走过的感觉是很重要的选择,走着走着,就笑了。
年轻的时候,就狂妄不羁吧。
老头子们说的事情,是他们自我否定之否定的过程。
如我直接成为一个老头,我何必走过我的20岁。
... -
2009-08-16
我姓梅
我姓梅,我是我爸妈生的,但我其实从来都闻不惯家里散发的铜臭味,看不惯爸妈那奇怪的面子问题。
有的时候我觉得,光吧孩子养成高大个子就算做父母成功了么?我妈深深的这样认为。。。。。。
我有的时候很庆幸像我这种经历的小孩其实应该不是网瘾就是变态。我在家里想和我妈聊天,我从来不觉她注意力会在我身上,她会时常在我说话的过程问:你明天穿什么?。。。我还问过她关心我什么?她说吃饭穿衣。。。。。。其实关于我这个梅家独子来说,他们基本除了钱没有怎么考虑过其他.他们的... -
2009-06-08
看着皂片
脑子里就浮了出来
我爱米井~~~
-
2009-05-04
cow....他是怎么办到的。。。
int a[2] = {100,200};
00E135BE mov dword ptr [a],64h
00E135C5 mov dword ptr [ebp-8],0C8h
int* p = a;
00E135CC lea eax,[a]
00E135CF mov dword ptr [p],eax
int tmpi = 1[p];
00E135D2 mov eax,dword ptr [p]
00E135D5 mov ecx,dword ptr [eax+4]
00E135D8 mov dword ptr [tmpi],ecx
tmpi = p[1];
00E135DB mov eax,dword ptr [p]
00E135DE mov ecx,dword ptr [eax+4]
00E135E1 mov dword ptr [tmpi],ecxdouble d[2] = {100.0,200.0};
00E13601 fld qword ptr [__real@4059000000000000 (0E157B0h)]
00E13607 fstp qword ptr [d]
00E1360A fld qword ptr [__real@4069000000000000 (0E15740h)]
00E13610 fstp qword ptr [ebp-34h]
double* pd = d;
00E13613 lea eax,[d]
00E13616 mov dword ptr [pd],eax
double tmp = 1[pd];
00E13619 mov eax,dword ptr [pd]
00E1361C fld qword ptr [eax+8]
00E1361F fstp qword ptr [tmp]
tmp = pd[1];
00E13622 mov eax,dword ptr [pd]
00E13625 fld qword ptr [eax+8]
00E13628 fstp qword ptr [tmp]博大精深。。。。莫非还记录了偏移量的类型。。。那我平时的便宜都是unsigned int啊。。。cow....他是怎么办到的。。。
-
2009-05-04
每天都要玩一玩
#include <stdio.h>
#define MUST_HAVE_BASE(D,B) do{must_has_base<D,B> i;}while(0)
#define MUST_BE_SUBSCRIPTABLE_AS_DECAYABLE_POINTER(T) do{must_be_subscriptable_as_decayable_pointer<T> i;}while(0)
#define MUST_BE_SUBSCRIPTABLE(T) do{must_be_subscriptable<T> i;}while(0)template <class D, class B>
struct must_has_base
{
~must_has_base()
{
void (*p)(D*,B*) = constraint;
}
private:
static void constraint(D* pd, B* pb)
{
pb = pd;
}
};template <class T>
struct must_be_subscriptable_as_decayable_pointer
{
~must_be_subscriptable_as_decayable_pointer()
{
void (*p)(T const&) = constraint;
}
private:
static void constraint(T const& T_is_not_decay_subscriptable)
{
sizeof(0[T_is_not_decay_subscriptable]);//can only be done by pointers
}
};template <class T>
struct must_be_subscriptable
{
~must_be_subscriptable()
{
void (*p)(T const&) = constraint;
}
private:
static void constraint(T const& T_is_not_subscriptable)
{
sizeof(T_is_not_subscriptable[0]);
}
};
class A
{
};class B:public A
{
public:
B operator[](size_t index) const;
B& operator[](size_t index);
};class C
{
};int main()
{
//////////////////////////////////////////////////////////////////////////
// Sample of decay-able pointerint a = 100;
int* p = &a;
printf("%d\n",0[p]);//
//////////////////////////////////////////////////////////////////////////
// Sample of MUST_HAVE_BASE
MUST_HAVE_BASE(B,A);
MUST_HAVE_BASE(int,void);
MUST_HAVE_BASE(C,A);//
//////////////////////////////////////////////////////////////////////////
// Sample of MUST_BE_SUBSCRIPTABLE
MUST_BE_SUBSCRIPTABLE(int*);
MUST_BE_SUBSCRIPTABLE(int[10]);
MUST_BE_SUBSCRIPTABLE(B);
MUST_BE_SUBSCRIPTABLE(C);//
//////////////////////////////////////////////////////////////////////////
// Sample of MUST_BE_SUBSCRIPTABLE_AS_DECAYABLE_POINTER
MUST_BE_SUBSCRIPTABLE_AS_DECAYABLE_POINTER(int*);
MUST_BE_SUBSCRIPTABLE_AS_DECAYABLE_POINTER(B);//
return 0;
} -
2009-05-04
带我走进新时代
MUST_HAVE_BASE constraint实现,估计还不是最终的方案,C++你够强大了。本人打算走侯捷路线,我看书我看书,我看没人译过的书
#define MUST_HAVE_BASE(D,B) do{must_has_base<D,B> i;}while(0)
template <class D, class B>
struct must_has_base
{
~must_has_base()
{
void (*p)(D*,B*) = constraint;
}
private:
static void constraint(D* pd, B* pb)
{
pb = pd;
}
};
class A
{
};class B:public A
{
};class C
{
};int main()
{
MUST_HAVE_BASE(B,A);
MUST_HAVE_BASE(int,void);//solutions on postcard please..作者很可爱啊
MUST_HAVE_BASE(C,A);
} -
2009-04-23
OnlyOnHeap昨天的面试题
OnlyOnHeap昨天的面试题,今天写了一下。。来不及了。。。。。。。模板化得时候有点傻。。。回来再改
class _OnlyOnHeap
{
public:
static T* NewHeapObject();
static void FreeHeapObject(const T * const pOnlyOnHeap);
protected:
_OnlyOnHeap(){};
_OnlyOnHeap(_OnlyOnHeap& _other){};
_OnlyOnHeap& operator=(const _OnlyOnHeap& _other){};
};
template <class T>
T* _OnlyOnHeap<T>::NewHeapObject()
{
return new T;
}
template <class T>
void _OnlyOnHeap<T>::FreeHeapObject( const T * const pOnlyOnHeap )
{
delete pOnlyOnHeap;
}
class A:public _OnlyOnHeap<A>
{
friend _OnlyOnHeap<A>;
protected:
A(){printf("construct A\n");}
~A(){printf("destruct A\n");}
};
int _tmain(int argc, _TCHAR* argv[])
{
//A I_am_on_stack;//compile error 无法访问 private 成员(在“_OnlyOnHeap<T>”类中声明)
//A* p_I_am_on_heap = new A;//compile error 无法访问 private 成员(在“_OnlyOnHeap<T>”类中声明)
A* p_I_am_on_heap = A::NewHeapObject();
A::FreeHeapObject(p_I_am_on_heap);
return 0;
} -
2009-04-16
还记得那天
六月三十号
八月三十号
-
2009-04-12
再次颓废
人累了,智力下降了,说明自然界规定了我获取知识的速度。。。
向左走,向右走。无论休息还是继续学人都不满足,似乎身体里的恶魔与天使都疯了。好吧,你们疯吧。
螃蟹在遇到蝎子的时候脱下了壳。
话说我以单纯的不再单纯,我慢慢知道类型不匹配不止发生在C++里。
很多以前的朋友,已经过不了编译了。我这样目的鲜明的人,是会毫不犹豫的把不能编译的部分改掉的。。。
我太残酷了。
世界太残酷了。
螃蟹壳还是穿回去的好。
好吧,世界就是为了让你去改正不能编译的部分的。。。虽然这也不能保证运行良好哦 。
-
2009-04-06
Inside The C++ Object Model
慢慢看啊看终于看完了这本书,一本很有深度的书。
说起来的话,这本书可以说是提供了制作编译器的参考与指导。但对于我,理解底层的工作原理必然也是有好处的,而且这种好处不仅仅在于c++的语言层面,也在于思想,严谨。

我看的是侯捷的译本,说起来原版的书错误真的是不少,如果直接抱起英文的可能读得云里雾里,好在侯捷同志工作敬业,译注写得很明白,看起来省心很多。呵呵,不过最后这位同志还是有点小偷懒。二义性ms都没有被翻译出来,都写成了暧昧不清,这对于绝大多数人来说就真的暧昧不清了。
总的说来是一本好书,有些部分很深,我也看了,看的时候也明白了。但是其中的思想,ms要积累更对经验才能领会。有人问过我看这本书有什么用。他的意思是知道这些东西没有用。呵呵,某种层面上来说用处是不大,如果只想使用RTTI,Template等等这本书是没必要的。但是这本书不仅告诉你c++底层可以怎么实现,也告诉你一个良好的系统的实现经验。
正所谓,如果只想活着的话不用在乎每顿饭的营养。。。。
-
2009-04-04
Beginning ASP.NET 2.0 with C#
两天看完了这本书。
为了学院网站,现学C#,以前虽然也用过,但怎么说呢,基本只是为了用用他的库,当作增强的c++来用,甚至觉得他的托管对我有限制,不好用。
但是基本上,看完这本书之后,了解了一些ASP.NET的强大功能。。。。。。

但毕竟这本书只是beginning......总的来说,C#这类语言在我看来是一个趋势。
C++啊。。。。。。
-
很认真的看完了这本书。。电子版的,相比较原书在图片和某些部分上有缺失。
总的来说收获是不小的,对于windows系统有了一个更好的认识,也对一些技术有了更好的了解。不过人家说的是win2000至于变化如何,我只能依赖于msdn了。结构化已成处理暂时被我跳过了,用的毕竟不多。

感谢亲爱的一直陪我去图书馆
-
2009-03-22
二叉树
我们一直在走,我拿起书,放下书。抬头回想。
世界究竟有多大,全我一生,我能知道多少,世界既是无限的,我为何要全我一生去探索?
抑或静静以自己所学,养活妻儿老小。那我便已把生命延续给下一代,期望他们能看穿宇宙世界。
生活是树,你从树根出发,怎样走向心中的叶子呢?有运气好的,他们走对了,而多数时候人们都到达了别的地方,落回根里,再独自出发。二叉树已是很难走得了,何况是多叉树。
我的叶子会在那儿?... -
2009-03-13
API HOOK 之 DLL代码修改 再之 放弃
之前使用修改PE头IMAGE_IMPORT_DISCRIPTOR的方法进行API HOOK网上资料大多都是这个,对于要遍历每一个模块很是不满。。。所以决定直接修改DLL代码,思想类似于THUNK,总的来说,仅仅对于HOOK API来说这是可行的
#pragma pack(push,1)
typedef struct _ThunkCode
{
unsigned char JMP;
DWORD Dest;
}ThunkCode;
#pragma pack(pop)int _stdcall A()
{
int i = 0;
++i;
return 0;
}int _tmain(int argc, _TCHAR* argv[])
{HMODULE hModule = LoadLibrary(TEXT("user32.dll"));
if (NULL == hModule)
{
printf("LoadLibrary fail\n");
return 0;
}void* ProcAddress = GetProcAddress(hModule,"MessageBoxW");
if (NULL == ProcAddress)
{
printf("GetProcAddress fail\n");
return 0;
}printf("proc address %p\n",ProcAddress);
void * Dest = A;
ThunkCode OriginalCode;
ThunkCode thunkCode;
thunkCode.JMP = 0xe9;
thunkCode.Dest = (int)Dest - (int)ProcAddress - sizeof(DWORD) - 1;
printf("%d\n",sizeof(thunkCode));
DWORD OriginalProtect;
::VirtualProtect(ProcAddress,sizeof(thunkCode),PAGE_EXECUTE_READWRITE,&OriginalProtect);
DWORD BytesRead;
::ReadProcessMemory(GetCurrentProcess(),ProcAddress,&OriginalCode,sizeof(OriginalCode),&BytesRead);
::WriteProcessMemory(GetCurrentProcess(),ProcAddress,&thunkCode,sizeof(thunkCode),&BytesRead);MessageBoxW(NULL,NULL,NULL,0);//断点断点
while(1);
return 0;
}在断点处反汇编:
011715C8 mov esi,esp
011715CA push 0
011715CC push 0
011715CE push 0
011715D0 push 0
011715D2 call dword ptr [__imp__MessageBoxW@16 (1178370h)]JUMP TO----》
7646D667 jmp A (1171104h)
JUMP TO----》
int _stdcall A()
{
01171420 push ebp
01171421 mov ebp,esp
01171423 sub esp,0CCh
01171429 push ebx
0117142A push esi
0117142B push edi
0117142C lea edi,[ebp-0CCh]
01171432 mov ecx,33h
01171437 mov eax,0CCCCCCCCh
0117143C rep stos dword ptr es:[edi]
int i = 0;
0117143E mov dword ptr [i],0
++i;
01171445 mov eax,dword ptr [i]
01171448 add eax,1
0117144B mov dword ptr [i],eax
return 0;
0117144E xor eax,eax
}大家看到了,是很成功的,但是我还是放弃了这种做法,为什么?
好了首先我进行试验验证DLL的代码段在系统中可能不只存在一份的,好,因此我写如下代码,调试:
int _tmain(int argc, _TCHAR* argv[])
{
MessageBoxW(NULL,NULL,NULL,0);
return 0;
}反汇编:
MessageBoxW(NULL,NULL,NULL,0);
00C913BE mov esi,esp
00C913C0 push 0
00C913C2 push 0
00C913C4 push 0
00C913C6 push 0
00C913C8 call dword ptr [__imp__MessageBoxW@16 (0C98338h)]-----》
7646D667 mov edi,edi
7646D669 push ebp
7646D66A mov ebp,esp
7646D66C cmp dword ptr ds:[76479CA8h],0!并无变化,为什么?在运行这一段程序时,之前修改API的程序并未退出。好原因就是Copy on write:
The MIcrosoft Windows NT, Windows 2000, or Windows XP's Copy on Write page protection is a concept that allows multiple applications to map their virtual address spaces to share the same physical pages, until an application needs to modify the page and have its own instance copy. This is part of a technique called Lazy Evaluation, which allows the system to not waste time by committing resources, time, or execution until/unless absolutely necessary. Copy on Write allows the virtual memory manager to save memory and execution time.
Copy on Write works as follows: In generic terms, an application can load something into its virtual memory (for example, a code section or DLL code). Virtual memory is mapped to physical memory. Another process may want to load the same thing into its virtual memory. As long as neither process writes to this memory, they can map to, and share, the same physical pages.
If either process needs to write to this memory, because the memory is marked as Copy on Write, the physical page frame will be copied somewhere else in physical memory. Fixups are made for the virtual memory mapping of the writing process. Both applications now have their own instance of the memory contents. In short, applications can share the same physical memory with Copy on Write, until one of the applications has to modify the contents. At that point, a new copy of the contents is made, and the writing process has its own copy.
也就是说,除非我可以将修改写入物理内存并且通知其他mapping的程序才有可能让修改对所有调用者起作用。同时如果需要全局的对API进行修改那么必然每个进程都会拥有一份DLL副本,问题是很严重的。同时,使用这个方法的问题在于我必须在调用原始API版本前恢复API前端5bytes的数据。形如:
void MySleep(int)
{
DisHook(Sleep);
Sleep(1000);
Hook(Sleep);
}
好Sleep用在这里是一个很好的例子,由于DLL对于Thread来说是共享的因此当多线程的情况下:
Thread1: MySleep {DisHook -》 Sleep(1000) ------------------》 Hook}
Thread2: 100ms-------》MySleep{//!!!DisHooked by Thread1!!} == Sleep()
好了,这是严重的同步问题,而且怎么解决呢?似乎很难,除非使用同步机制,那就明显很有可能的使系统表现出异样的运行状态。
同步的问题并没有真正写代码予以验证,不过相信这是不会有问题的。
有感于今天敏锐的嗅觉和昨天的愚钝。
-
2009-02-28
solution to thunk under DEP (2)
思路是正确的,问题是不能用operator new因为发下这样thunk用起来就不方便了。。。主要改动了一下构造和析构函数
typedef struct _ThisToStdThunkCode
{
_ThisToStdThunkCode(){};
#pragma pack(push,1)
unsigned char MOV_ECX;
const void* m_this;
unsigned char JMP;
int m_MemFunc;
#pragma pack(pop)
}ThisToStdThunkCode;class ThisToStd
{
public:
ThisToStd(const void* pObj = 0, int MemFunc = 0);
~ThisToStd();
const void* Attach(const void * pObj);
int Attach(int MemFunc);
private:
ThisToStdThunkCode* m_Code;
};ThisToStd::ThisToStd( const void* pObj /*= NULL*/, int MemFunc /*= 0*/ )
{
bool bresult = IsProcessorFeaturePresent(12);//Data execution prevention is enabled
if (bresult)
{
m_Code = reinterpret_cast<ThisToStdThunkCode*>(VirtualAlloc(NULL,sizeof(ThisToStdThunkCode),MEM_COMMIT,PAGE_EXECUTE_READWRITE));
}
else
{
m_Code = new ThisToStdThunkCode;
}
m_Code->JMP = 0xE9;
m_Code->MOV_ECX = 0xB9;
Attach(pObj);//设置this指针
Attach(MemFunc);//设置跳转偏移
}ThisToStd::~ThisToStd()
{
if (IsProcessorFeaturePresent(12))
{
VirtualFree(m_Code,sizeof(ThisToStdThunkCode),MEM_RELEASE);
}
else
{
delete m_Code;
}
}全部搞定~,至少目前是这样
使用起来很方便,因为可以注意到ThisToStd类只有一个指针成员,因此可以直接把ThisToStd转型成函数指针调用。
pointer_cast 和union_cast是这两天学来的,自已写了个,真的很好用。。。
sample:
#include "cast.h"
using namespace cast;
#include <stdio.h>class A
{
public:
A(int _a = 0):a(_a){};
int show(int i){printf("thunk under DEP , a = %d, i = %d",a,i);return 0;}
int a;
};typedef int (__stdcall * func)(int);
int main()
{A a;
ThisToStd thunk(&a,pointer_cast<int>(&A::show));
func func1 = pointer_cast<func>(thunk);
func1(10);
return 0;
}哈哈哈哈~好开心
-
2009-02-28
solution to thunk under DEP (1)
ATL thunks and Windows DEP story
When using older ATL versions the program may generate an access violation due to Data Execution Prevention. This is basically a memory protection feature that prevents executing code from memory pages marked as non-executable.说明不只我碰上这个问题,然后发现解决之道,result = IsProcessorFeaturePresent( 12 /*PF_NX_ENABLED*/ );确定处理器是否开启DEP若开启的话thunk代码必须分配在PAGE_EXECUTE_READWRITE属性的页面上修改结果: -
2009-02-28
vista business 搞死我thunk
今天很大胆的进行__thiscall到__stdcall调用约定thunk转换的封装,受waterloo学长启发,进行自我漫长的探索道路,基本就是参照waterloo的做法写的,由于用的是IBM的本本,32位vista business版,第一次运行不成功,反汇编,看到call后执行了
cmp esi,esp
call __chkesp
上一篇文章提到过的老问题,解决办法目前是使用release
好的release后,运行结果发现弹出一个框框上写:PointerCast.exe停止工作,数据执行保护
原来是DEP,数据执行保护 (DEP) 是一种安全功能,它通过监视您的程序确保它们使用的系统内存是安全的来帮助防止受到病毒和其他安全威胁的破坏。
我就说为什么我thunk直接RET也跳出。。。这下好了,我的exe连加入例外他都不允许,还写着您的CPU支持硬件DEP。。。。。。彻底无语。。。。。。
只有到学校再调试了。。。。。。
不过这应该也意味着thunk在较安全的系统中的局限性
-
2009-02-27
线程注入
最近好像都在学有点黑的东西。。。。。。
好我们来看一下线程注入,也就是向远端的进程中注入一个线程
依然是老风格:
-1)那首先你要有一个线程函数:
static DWORD __stdcall ThreadProc(void* LpPara)
{
RemoteParam* Param = static_cast<RemoteParam*>(LpPara);
RemoteMessageBoxA MessageBox = Param->Pointer;
int i;
MessageBox(NULL,Param->buffer,Param->buffer,0);
//Sleep(3000);
return 0;
}
static void AfterThreadProc(){};为什么要下一个AfterThreadProc内?而且为什么要用static内?
因为:DWORD CodeSize = (LPBYTE)AfterThreadProc-(LPBYTE)ThreadProc;可以轻松得到代码大小。
0)由于远端进程与本进程地址空间不同,所以本地的数据必须先拷贝过去,再将拷贝到的地址用参数传过去
因此定义一个数据结构,放参数用
typedef int (__stdcall * RemoteMessageBoxA)(HWND,LPCSTR,LPCSTR,DWORD);
struct RemoteParam
{
RemoteMessageBoxA Pointer;
char buffer[1024];
};因为结果很难展现,所以吧MessageBoxA的函数入口一起传过去。函数入口是这样取得的:
RemoteParam remoteParam;
HINSTANCE hUser32 = ::LoadLibrary(L"user32.dll");
remoteParam.Pointer = (RemoteMessageBoxA)::GetProcAddress(hUser32,"MessageBoxA");
strcpy(remoteParam.buffer,"Injected");以上这招很实用。
1) 找出宿主进程ID,这次在网上看到ToolHelp32的方法:
HANDLE WINAPI CreateToolhelp32Snapshot(
__in DWORD dwFlags,
__in DWORD th32ProcessID
);
BOOL WINAPI Process32First(
__in HANDLE hSnapshot,
__in_out LPPROCESSENTRY32 lppe
);
BOOL WINAPI Process32Next(
__in HANDLE hSnapshot,
__out LPPROCESSENTRY32 lppe
);这样就遍历了所有的进程,根据PROCESSENTRY32中的信息找到进程ID即可。
2)打开进程句柄
HANDLE WINAPI OpenProcess(
__in DWORD dwDesiredAccess,
__in BOOL bInheritHandle,
__in DWORD dwProcessId
);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,processID);好了,准备就绪。
3)分配内存
LPVOID WINAPI VirtualAllocEx(
__in HANDLE hProcess,
__in LPVOID lpAddress,
__in SIZE_T dwSize,
__in DWORD flAllocationType,
__in DWORD flProtect
);
在远端进程上分配足够放下数据和代码的内存。void* pRemoteThread = ::VirtualAllocEx(hProcess,NULL,CodeSize,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
if (!pRemoteThread)
{
return -1;
}void* pRemoteParam = ::VirtualAllocEx(hProcess,NULL,sizeof(RemoteParam),MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);
if (!pRemoteParam)
{
return -1;
}注意权限的设置,具体细节查看MSDN,我试着去掉了MEM_RESERVE运行依然正常,但MSDN似乎说这是有可能出错的。
4)好了,在远远的进程上,我们已经准备好了空间,现在就差数据了,其实也很简单,我在内存搜索的时候已经提到过了。
BOOL WINAPI WriteProcessMemory(
__in HANDLE hProcess,
__in LPVOID lpBaseAddress,
__in LPCVOID lpBuffer,
__in SIZE_T nSize,
__out SIZE_T* lpNumberOfBytesWritten
);
DWORD BytesWritten = 0;if (!::WriteProcessMemory(hProcess,pRemoteParam,&remoteParam,sizeof(remoteParam),&BytesWritten))
{
return -1;
}
if (!::WriteProcessMemory(hProcess,pRemoteThread,ThreadProc,CodeSize,&BytesWritten))
{
return -1;
}5)终于的终于,我们的代码和数据在飞到了远远地进程上,接下在,我们只要让我们的代码运行起来就行。让他作为一个线程运行起来。
HANDLE WINAPI CreateRemoteThread( __in HANDLE hProcess, __in LPSECURITY_ATTRIBUTES lpThreadAttributes, __in SIZE_T dwStackSize, __in LPTHREAD_START_ROUTINE lpStartAddress, __in LPVOID lpParameter, __in DWORD dwCreationFlags, __out LPDWORD lpThreadId );
DWORD ThreadID = 0;
HANDLE hRemoteThread = ::CreateRemoteThread(hProcess,0,0,(DWORD (__stdcall*)(void*))pRemoteThread,pRemoteParam,0,&ThreadID);
if (!hRemoteThread)
{
return -1;
}好了,到这里,不论你在线程函数里写了什么,你应该看到效果了,对于第一次写的同志们,包括写了好久的我,很有可能你看到的内存访问错误!一种可能是你在代码大小计算上出了错,还有一种可能是,你没用使用release生成。我在这里堵住很久,网上终于查到是因为 DEBUG版本的————chkesp函数导致非法地址,不知那位牛人是怎么知道的。
7)好了,大家应该玩得很开心,但是为了以后也玩的开心不要忘了善后:
DWORD exitCode = 0;
::WaitForSingleObject(hRemoteThread,INFINITE);
::GetExitCodeThread(hRemoteThread,&exitCode);
::CloseHandle(hRemoteThread);::VirtualFreeEx(hProcess,pRemoteParam,sizeof(remoteParam),MEM_RESERVE);
::VirtualFreeEx(hProcess,pRemoteThread,CodeSize,MEM_RESERVE);
::CloseHandle(hProcess);参考少量也不少的网上资料自我总结而成。。。。。ms是个很好玩的东西
-
2009-02-26
新学一招。。Thunk
unsigned char machine_code [] = {0xEB, 0x00,0xC3};
//00: short Jump
//01: 0x00
//02: Returnvoid* paddr = machine_code;
void (*fn_ptr) (void) = (void (*) (void)) paddr;
fn_ptr ();
/*
偏移量 机器码
=========== ======
(-128) 0x80 ??
(-127) 0x81 ??
:
:
(-3) 0xFD ??
(-2) 0xFE EB <- Short JMP指令
(-1) 0xFF XX <- XX为跳转偏移量,其取值范围可为[0x80 - 0x7F]
(0) 0x00 ?? <- JMP下一条指令的开始位置
(+1) 0x01 ??
(+2) 0x02 ??*/
void foo(int a)
{ printf ("In foo, a = %d\n", a); }unsigned char code[9];
* ((DWORD *) &code[0]) = 0x042444FF; /* inc dword ptr [esp+4] */
code[4] = 0xe9; /* JMP */
* ((DWORD *) &code[5]) = (DWORD) &foo - ((DWORD) &code[0] + 9); /* 跳转偏移量 */
// foo 到 jump 下一条指令的偏移void (*pf)(int) = (void (*)(int)) &code[0];
pf(1);
代码基本是抄来的。。。整理了一下注释,备记。。。。。。
这技术还是很好玩的,原址:
-
2009-02-20
心有多大
就能装下多少
慢慢装下了之后又看见了自己的孤独。
大家好,我是小狼
平时很温顺的小狼,
我在追寻
内心焦虑
焦虑,我回身看
什么。。。背后的绳索。。。
大家好,我是小狗
平时很凶的小狗
我在挣脱
内心冲动
冲动,请放开我,或我咬断你
心有多大?什么是善?
作为中国人,作为我们,
是闭目养神放弃追逐
还是拼命挣扎心有不甘
大家好,我是小狼,
长大意味着我的轻狂
-
2009-02-03
内存搜索(2)原创。。。
今天执行了昨天的计划,一大早起来看书写程序。还是那个内存搜索。完全靠比对内存的方法已经没问题了。今天为了方便大众打算直接找一个值。大家知道同一个值有很多可能的内存形式。byte,short,int,long。而且还有unsigned这种东西,而且对于浮点不管,那个看样子还是直接比对内存吧。。暂时没想出办法
给大家看看内存实验的代码。。。基本属于垃圾代码,主要看结果。。。这个结果我估计弄弄又忘了
我是依靠移位的方法办的,大家记住内存里高位在高位,移位的方法很好的解决了正数值的问题,但对附属还是有问题:
int a = 1024;
byte* test = (byte*)&a;int b = test[0] | test[1] << 8 | test[2] << 16 | test[3] << 24;
byte* test1 = (byte*)&b;int* c = (int*)test;
byte* test2 = (byte*)c;
第二条结果是吧a的类型改成unsinged short
然后可想而知的,如果short的值是负的,移位之后int的高位就不对了,无法表示成一个负值。
明天再慢慢想,莫非还是要用类似上述c的方法进行类型转换?但是那样代码会很恶心。。。。
还有,大家注意了,使用
HWND FindWindow(
LPCTSTR lpClassName,
LPCTSTR lpWindowName
);时如果只给出lpWindowName以下两个窗口被认为是相同的,因此都有可能成为返回值。。。。

这直接导致我早上无数次测试错误。。。。。
-
2009-02-01
果然改成了
占地留贴,先去吃饭。
侯捷,俺听你的。。。。。。虽然你只是翻译的
-
2009-01-31
孩子
卡卡西说,作为忍者,就要面对比自己强的人
是啊,知道的越多越觉得自己还差很远。有的时候想想,好几天没摸程序了,目的是写通用的内存搜索,然后想想,要支持int,double,字符串,死脑子,上篇写了,字符串搞定了,别的后来就没动,一直在看书,然后发现四人帮的设计模式的确是圣经,它提供思想。
Decorator并没什么特别的,但我脑子好,边看边想,傻看无用,理解至上,他有缺点,有优点,按我看effective c++中的思想,我想到Decorator用的过分会有严重的overhead,但是我脑子又不好,我自己还没想到解法。神人就是神人,看看人家对NULL的重定义,你会觉得自己缩小了,人家一牛逼NULL,全全没有overhead。再看看我之前对搜索的想法。。。我更小了,你个傻子,你应该已经做完了,既然是内存搜索,你直接搜索内存呗,你用什么strlen来得到字符串长度干什么?你直接给段内存,给段长度,不就都有了,什么int,double。。。
四人帮说:an application needn't pay for features it doesn't use是啊,内存就足够了,接下来就是设计扩展性的问题。。。我怀疑。。。我也就明天再改改代码。。。人最近很懒
如果你不会过苦日子,你还需努力么?
如果你长大有车有房,你还要努力么?
比较有想象力的回答是。。。。。。如果我的孩子长大了呢?
——全英版的书好,因为四人帮是神。。。
——台版的effective c++好,因为侯捷是我老师~ 我自豪!。。。。
编者注:此文中“四人帮”非彼四人帮,此四人乃设计模式神级人物。名之曰:gang of four。鉴于此文带有政治敏感词汇,请勿转载。
-
2009-01-18
内存搜索(1)原创。。
无它但手熟尔。。很明显的,C/C++是很久没有写了,久到忘记了using namespace。。。
内存这一块还是很生疏,所以为了防止以后忘掉,先来写一下。。。
记住API即可:
首先是获得进程句柄
HWND FindWindow(
LPCTSTR lpClassName,
LPCTSTR lpWindowName
);DWORD GetWindowThreadProcessId(
HWND hWnd,
LPDWORD lpdwProcessId
);HANDLE WINAPI OpenProcess(
__in DWORD dwDesiredAccess,
__in BOOL bInheritHandle,
__in DWORD dwProcessId
);这样进程句柄就到手-------------------------------------------------
然后关心一下系统属性,主要是用户区内存上下界。
void WINAPI GetSystemInfo(
__out LPSYSTEM_INFO lpSystemInfo
);上下界到手----------------------------------------------------------
然后就是重点了,扫描进程的用户区内存。
SIZE_T WINAPI VirtualQueryEx(
__in HANDLE hProcess,
__in LPCVOID lpAddress,
__out PMEMORY_BASIC_INFORMATION lpBuffer,
__in SIZE_T dwLength
);对commit状态的内存按页分割。
一页一页的内存到手---------------------------------------
写函数爱干啥干啥吧吧~~~呵呵,刚开始也目标测试程序的时候犯傻了
对变量temp进行地址搜索,但是变量temp是这样的
char* temp;
省略无数字
temp = "123123";
再略无数字
temp = "12341234";
然后看到内存里有无数123123,12341234但是没有地址与变化前的匹配。话说人傻就是没办法。
目前只完成了对内存中字符串的匹配,ms据说这样可以直接从内存里抽出qq密码~~嘿嘿,对Int还是找不到,今天继续,感觉Int在内存里不是按32bit对齐的,不然应该找到了。。。
发现无论什么东西写出来就是不做起来简单,所以还是得做
-
2009-01-01
过年了
么回家,爸妈新年好~
今年可以结婚了。。。老婆同志很害怕见我妈。。。汗。。。。
胆小的来。。。
不过反正俺也不急。。。反正米井同学我吃定了~~哈哈哈
睡觉中的米同学现在一定还在睡觉。。。嘿嘿,米老鼠同学新年好~~哈哈哈
谁说我不写博客的?告诉你,我是忘记密码了。。。。好不容易找回来了。。。
过年了,我有一个最大的新年愿望~~~让全世界的傻逼们都消失吧~~除了我... -
2008-11-28
大螃蟹
喏,我又来写了,话说呢~我是大坏蛋
我是大坏蛋~哈哈哈哈
我内心强大的占有欲告诉我,小米井~~我吃定你了
我是大螃蟹~~
-
2008-11-19
跟我走
跟我走
不管去哪里,只要有我有你
剩下的就是苦日子后的好日子







