|
|
jmp跟popad的疑问
好的,我试试! |
|
|
jmp跟popad的疑问
你好,我是新手,请问jmp回上一层函数后,如何手动平衡堆栈呢? |
|
|
jmp跟popad的疑问
你好,谢谢你昨天的帮忙,嘿嘿~ 我是按照你昨天的答复改用call的,改call之后,因为覆盖了原始代码1个字节,所以顺便nop掉后2个字节,然后在call执行完后,也就是这个asm代码最后jmp回以前nop x 2后的下一个地址 但是jmp回去后,发现堆栈不平衡的,导致上一层的主函数在retn 8 后,返回到了另外一个地址:( |
|
|
hook call疑问
0196B33F 8B10 mov edx, dword ptr [eax] 0196B341 53 push ebx 0196B342 55 push ebp 0196B343 8BC8 mov ecx, eax // jump call 0196B345 FF52 10 call dword ptr [edx+10] 0196B348 8BCF mov ecx, edi // +1+2 nop掉 0196B34A 83E1 1F and ecx, 1F 以上是源代码,我hook了0x196B345改为call newFunction,请问,从0x196B33F~0x196B343都是给call dword ptr[edx+10]压栈,那么我在newFunction里面如何调用前面push进去的参数呢? 函数原型是: void newFunction(int,struct *ptr) { } |
|
|
hook call疑问
占用了83不说,结果我的MyProc最后一句Done也打印不出来,直接挂掉了! |
|
|
hook call疑问
那个call dword ptr [edx+10]就是我想替换掉的函数,他原本只占用了3个字节 我在vc中的代码如下: __declspec(naked) void newCall(int a,strcut_s *ptr) { __asm { pushad; call MyProc;//我自己的算法函数 mov ecx, edi popad; ret; } printf("Done.\n"); } 就这样一个函数,如果他的指针只占用5个字节,那么就应该替换掉: FF 52 10 call dword ptr [edx+10] 8B CF mov ecx, edi 结果是替换掉了,还多占用了一个字节,把下一语句的83 E1 1F and ecx, 1F 给占用了,结果下一语句变成了:E1 1F loopde short XXXXXX 无语。。。 |
|
|
hook call疑问
感谢aait的帮助,另外我再问一下: 我call成功后在OD里面查看,它占用了6个字节,不知道是不是apihook类的问题。。。 那么原本正常代码是这样: FF 52 10 call dword ptr [edx+10] 8B CF mov ecx, edi 83 E1 1F and ecx, 1F 我改了call后,变成了: 69:E9 5E7A690E jmp XXXXXX E1 1F loopde short XXXXXX 83这个字节被我的call给覆盖掉了。。。 |
|
|
hook call疑问
明白了,感谢指点! |
|
|
hook call疑问
忘记一点,我不可以直接hook红色的函数,因为这个原始函数会有很多地方调用,所以我只能屏蔽Fun.A中调用它的代码,替换成我自己的另一个函数call,但是又不能影响Fun.A下面的move ecx,edi蓝色部分。 不知道我的描述是否清楚,请见谅! |
|
|
[讨论]关于remotethread注入后的回调的执行(PE)
感谢skypismire的指点,项目是在目标进程运行中进行远程注入的,而目标进程在运行时没有调用GetProcAddress,所以我的CallBack.B木有机会被执行到。 换了个函数就能hook到,并执行我的CallBack.B了~ thx! |
|
|
[讨论]关于remotethread注入后的回调的执行(PE)
事实上,注入的dll进到DLL_PROCESS_ATTACH里面,PECall也执行到pThunk->u1.Function = pNewFunction;这一步了,就剩下CallBack.B(newGetProcAddress )没有进入。。。 CallBack.B回调函数如下: FARPROC ( WINAPI *pGetProcAddress )( HMODULE hModule, LPCSTR lpProcName ); FARPROC WINAPI newGetProcAddress( HMODULE hModule, LPCSTR lpProcName ) { MessageBox(0,"newGetProcAddress",0,0); } |
|
|
[讨论]关于remotethread注入后的回调的执行(PE)
这个修改PE表的函数原型是: void *PECall( HMODULE hModule, char *szDllName, char *szFunctionName, DWORD pNewFunction ) 我在dllmain里面是这样调用的: switch (xxx): { case DLL_PROCESS_ATTACH: { pGetProcAddress = ( FARPROC(WINAPI*)(HMODULE,LPCSTR))PECall(GetModuleHandle(NULL) ,"Kernel32.dll" ,"GetProcAddress" ,(DWORD)&newGetProcAddress ); } } |
|
|
[讨论]关于remotethread注入后的回调的执行(PE)
pNewFunction是我传入的一个DWORD指针,他是CallBack.B的入口地址,就是我举例的那个0x12345678 |
|
|
[讨论]关于remotethread注入后的回调的执行(PE)
不好意思,我打字太懒了。。。 PIMAGE_THUNK_DATA pThunk; pThunk = MakePtr( PIMAGE_THUNK_DATA, pDosHeader, pImportDesc->FirstThunk ); while( pThunk->u1.Function ) { // 如果找到szFunctionName(GetProcAddress)的基地址 if( pThunk->u1.Function == (DWORD)pOldFunction ) { DWORD dwOldProtect; BOOL ret = VirtualProtect( ( void * )&pThunk->u1.Function, sizeof(DWORD), PAGE_READWRITE, &dwOldProtect ); log("A.ret = 0x%X , pNewFunction = 0x%X , dwOldProtect = 0x%X",ret,pNewFunction,dwOldProtect); pThunk->u1.Function = pNewFunction; ret = VirtualProtect( ( void * )&pThunk->u1.Function, sizeof(DWORD), dwOldProtect, &dwOldProtect ); log("B.ret = 0x%X , pNewFunction = 0x%X , dwOldProtect = 0x%X",ret,pNewFunction,dwOldProtect); return( pOldFunction ); } pThunk++; } |
|
|
[讨论]关于remotethread注入后的回调的执行(PE)
我用IDA动态加载目标进程,然后用loader.exe将dll注入进去,单步调试,也进入到pthunk->u1.function=CallBack.B这句,这时CallBack.B的地址显示也是对的(0x12345678),然后我在IDA里面用G跳转到0x12345678,正好是CallBack.B函数的入口地址,这点也是正常的。 我就奇怪了,既然我都将CallBack.B的入口地址传给pthunk->u1.function了,为什么没有执行到CallBack.B这个函数呢?我在里面用了MessageBox,也没框弹出来。。。 |
|
|
[原创]进程中dll模块的隐藏
修改pe头呢? |
操作理由
RANk
{{ user_info.golds == '' ? 0 : user_info.golds }}
雪币
{{ experience }}
课程经验
{{ score }}
学习收益
{{study_duration_fmt}}
学习时长
基本信息
荣誉称号:
{{ honorary_title }}
勋章
兑换勋章
证书
证书查询 >
能力值