1、在我的DLLMain中加载系统的 ws2_32.dll, 并把 ws2_32.dll中的所有函数地址都保存下来, 例如:
FARPROC connectAddr = GetAddress("connect");
2、在我的导出函数中直接调用真正的函数地址, 例如:
ALCDECL MyHijack_connect(void)
{
__asm JMP connectAddr;
}
主程序可以正常运行, 并且可以调用到我的dll
但是如果我想在程序中做些什么, 比如想查看新连接的地址和端口, 如下
ALCDECL TESTInet_ntoa(in_addr addr)
{
__asm JMP inet_ntoaAddr;
}
void __cdecl PrintConnect()
{
void* espaddr = NULL;
__asm mov espaddr, ebp;
int Sock = *((int*)((char*)espaddr + 8));
struct sockaddr_in* addr = *(struct sockaddr_in**)((char*)espaddr + 12);
int nameLen = *((int*)((char*)espaddr + 16));
USHORT port = addr->sin_port;
char* linkaddr = NULL;
__asm
{
mov eax, 0;
mov ax, word ptr port;
push eax;
call ntohsAddr;
mov port, ax;
}
TESTInet_ntoa(addr->sin_addr);
__asm mov linkaddr, eax;
char buf[22] = { 0 };
sprintf_s(buf, "%s:%d", linkaddr, port);
MessageBoxA(NULL, buf, "新连接", MB_OK);
__asm mov esp, ebp;
__asm pop ebp;
__asm ret;
}
ALCDECL MyHijack_connect(void)
{
__asm
{
sub ESP, 12;
push esi;
push edi;
push eax;
MOV esi, esp;
add esi, 28;
MOV edi, esp;
add edi, 12;
MOV eax, [esi];
MOV [edi], eax;
add esi, 4;
add edi, 4;
MOV eax, [esi];
MOV [edi], eax;
add esi, 4;
add edi, 4;
MOV eax, [esi];
MOV [edi], eax;
pop eax;
pop edi;
pop esi;
call PrintConnect;
}
__asm add esp, 12;
__asm JMP connectAddr;
}
可以弹出俩个新连接的窗口, 但是之后程序就没反应了, 任务管理器里进程也没了, 我查看了调用完 PrintConnect 出来后的esp也就是 __asm add esp, 12; 这时候的esp值和刚进MyHijack_connect时的值一样, 不知道为什么会启动不了
还有就是如下代码也不行
void __cdecl PrintConnect()
{
__asm JMP connectAddr;
}
ALCDECL MyHijack_connect(void)
{
__asm JMP PrintConnect;
}
完全没有动esp, 为什么多了一层 jmp 后程序就不正常了呢
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)