五 修正jmp走的IAT操作
可以关掉程序了
---------------------------第二个程序---------------------------------
#include <Windows.h>
#include <stdio.h>
void main(void)
{
FILE *fp = fopen("e:\\1_.exe", "rb");
char *mapoffile = new char[0x42000]; //文件大小0x42000
fread(mapoffile, 0x42000, 1, fp); //文件内容全读进来
fclose(fp);
fp = fopen("e:\\api.bin", "rb");
char apibuf[16];
DWORD dwPrevApiAddr = 0;
DWORD dwApiAddr = 0;
DWORD dwIatAddr = 0x400000 + 0x40000;
DWORD dwRCall;
int r = fread(apibuf, 16, 1, fp);
dwPrevApiAddr = *(LPDWORD)apibuf;
while (r !=EOF && r != 0)
{
// 得到IAT的位置
dwApiAddr = *(LPDWORD)apibuf;
if (dwPrevApiAddr != dwApiAddr)
dwIatAddr += 4;
if (*(LPDWORD)(dwIatAddr-0x400000+mapoffile) == 0)
dwIatAddr += 4;
dwPrevApiAddr = dwApiAddr;
// 找偷掉API操作的字节长度
// 比如 CALL [0x00CD****] 是6个字节
// MOV EAX, [0x00CD****] 是5个字节
for (int i=4; i<16; i++)
{
if (*(LPWORD)&apibuf[i] == 0x00CD)
break;
}
//通过跳回去的地址算出跳进来的地址
dwRCall = *(LPDWORD)&apibuf[i-2] + 4 + 5 + *(LPDWORD)&apibuf[i+3];
//把 jmp CD**** 改回 CALL [IAT]. MOV EDI, [IAT] 等等
memcpy((LPVOID)(dwRCall-0x400000+mapoffile), &apibuf[4], i-2-4);
memcpy((LPVOID)(dwRCall-0x400000+mapoffile+i-2-4), &dwIatAddr, 4);
r = fread(apibuf, 16, 1, fp);
}
fclose(fp);
// 2.exe是最终文件
fp = fopen("e:\\2.exe", "wb");
fwrite(mapoffile, 0x42000, 1, fp);
fclose(fp);
delete[] mapoffile;
}