如果向 PE 文件添加额外的导入部分是可以接受的选项
使用 iidking 之类的工具并添加一个导入部分,其中包含所有动态解析的导入
使用添加交叉引用对话框或 idc add_dref() 向它们添加交叉引用
演示代码
#include <stdio.h>
#include <windows.h>
#pragma comment(lib , "user32.lib")
DWORD (WINAPI * MyGetShortPathName)(LPCTSTR,LPTSTR,DWORD);
int main (void) {
MessageBox(NULL,"testing add import" , "Test", MB_OK);
char modname[MAX_PATH] = {0};
GetModuleFileName(NULL,modname,MAX_PATH);
printf("%s\n",modname);
HMODULE hMod = LoadLibrary("kernel32.dll");
if(hMod) {
*(FARPROC *)&MyGetShortPathName = GetProcAddress(hMod,"GetShortPathNameA");
if(MyGetShortPathName) {
MyGetShortPathName(modname,modname,MAX_PATH);
printf("%s\n",modname);
}
}
return 0;
}
编译并执行
C:\codesnips\addimp\addimp.exe
C:\CODESN~1\addimp\addimp.exe
未修改的进口
00412000 GetCurrentThread KERNEL32
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
00412130 MessageBoxA USER32
使用 iidking 修改的 exe 和在额外导入部分中添加的导入 GetShortPathNameA
C:\codesnips\addimp>fc /b addimp.exe modaddimp.exe
Comparing files addimp.exe and MODADDIMP.EXE
000000E6: 04 05 no of section
00000131: 90 A0
00000160: F4 00
00000161: 47 90
00000164: 3C 50
00000278: 00 2E .
00000279: 00 49 I
0000027A: 00 49 I
0000027B: 00 44 D
0000027C: 00 4B K
0000027D: 00 69 I
0000027E: 00 6E N
0000027F: 00 67 G
00000281: 00 02 vsize
00000285: 00 90
00000286: 00 01
00000289: 00 02
0000028D: 00 5E
0000028E: 00 01
0000029C: 00 20
0000029F: 00 E0
ida导入修改后的exe窗口复制粘贴
00412000 GetCurrentThread KERNEL32
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
00412130 MessageBoxA USER32
00419058 GetShortPathNameA kernel32
双击 419058 -> 打开视图 -> 打开子视图 -> 交叉引用 -> 添加交叉引用
Up P sub_401000+89 call ds:GetProcAddress (data xref)
或 idc 命令
add_dref(0x401089,0x419058,53);
AddCodeXref(0x419058,0x401089,53);
将这三行编译成插件会将 Desired 导入添加到第一个模块的导入中
void idaapi run(int) {
nodeidx_t index = import_node.alt1st();
unsigned long value = import_node.altval(index);
netnode(value).supset(0x410004,"GetShortPathNameA\0");
}
用于创建 Segment 的 idc 文件
#include <idc.idc>
static main()
{
auto addr;
addr = 0x410000;
SegCreate(addr,addr+0x200,0,1,3,2);
SetSegmentType(addr,SEG_XTRN);
MakeDword(addr+4);
MakeName(addr+4,"GetShortPathNameA");
}
打开一个 exe / 运行 idc / 插件 / 关闭并保存数据库 / 重新打开数据库以查看第一个模块的导入选项卡中添加的导入
编辑
窗口 -> 重置桌面的工作方式与关闭和打开数据库的方式相同,从而避免关闭和打开数据库