E8 E9后的地址公式如下: X = 真正要跳转的地址 - E8这一条指令的下一行指令 等价于 X = 真正要跳转的地址 - (eip + 5) E8 X E9 X BYTE ShellCode[]={0x6A,0x00,0x6A,0x00,0x6A,0x00,0x6A,0x00,0xE8,0x00,0x00,0x00,0x00,0xE9,0x00,0x00,0x00,0x00}; //pImageBuf 我们在堆上分配的,首地址, 即为内存的首地址 //ImageBase 为内存中运行时的首地址 void *pAddAddress = (void *)((DWORD)pImageBuf + pISH->VirtualAddress + pISH->Misc.VirtualSize); memcpy(pAddAddress,pShellCode,dwShellCodeSize); //进行地址修正 HMODULE hMod = LoadLibrary("User32.dll"); //我们要执行的函数 *(DWORD *)((BYTE*)pAddAddress + 9) = (DWORD)GetProcAddress(hMod,"MessageBoxA") - ((DWORD)ImageBase+pISH->VirtualAddress + pISH->Misc.VirtualSize+8) - 5; //跳到原来程序要执行的位置 *(DWORD *)((BYTE*)pAddAddress + 14) = ImageBase+AddressOfEntryPoint - ((DWORD)ImageBase+pISH->VirtualAddress + pISH->Misc.VirtualSize+13) - 5; //重新修改入口地址, 首先让程序去执行我们的函数; pINGS->OptionalHeader.AddressOfEntryPoint = pISH->VirtualAddress + pISH->Misc.VirtualSize;
注意:ShellCode 是放在pImagebuff中的, 但是E8 E9后面的地址是imagebase中的地址