Call @F ;本条指令后一个@@标号
@@:
Pop ebx
Sub ebx, offset @B ;本条指令前一个@@标号
Call @F 把Pop ebx一句的地址压栈,然后jmp到Pop ebx一句的地址执行,执行完毕后ebx等于Pop ebx一句所在地址,即运行时的地址。
Sub ebx, offset @B用运行时地址减去编译时地址,得到两者之差,即偏移。后续对全局变量的访问可通过mov eax, [ebx + offset XXX]的形式访问。
函数重定位时,先在自己程序中找到API地址,将地址填入.code段的变量中,并以
Call [ebx + g_pfnXXX]的形式调用。
.code
CODE_BEGIN:
g_pfnGetLocalTime dword ?
g_pfnwsprintfA dword ?
g_pfnCreateFileA dword ?
g_pfnWriteFile dword ?
g_pfnCloseFile dword ?
g_pfnSleep dword ?
g_sysTime SYSTEMTIME <>
g_szTimeFormat byte '%4hd/%2hd/%2hd %2hd:%2hd:%2hd', 0
g_szBuf byte 64 dup(?)
nop
nop
nop
nop
nop
nop
nop
nop
CODE_START:
call @F
@@:
pop ebx
sub ebx, offset @B
lea eax, [ebx + offset g_sysTime]
push eax
mov eax, [ebx + offset g_pfnGetLocalTime]
call eax