DLL时你必须知道原有DLL中的函数都有哪些,以免导至其它进程调用DLL时找不到相应的API函数
,特别是在替换系统DLL文件时更要小心。
第六种方法:
无DLL注入
在第三中方法中,我们启动远程线程时,线程函数是我们从Kernel32.dll中取得的
LoadLibrary函数的地址为线程函数的地址,其实我们可以直接将线程函数体和函数参数写入目标
进程的地址空间,然后创建远程线程。
使用这个方法时,需要注意以下几个问题:
(1) 远程线程函数体不得使用kernel32.dll,user32.dll以外的函数。因为这个两个模块在
各个进程的相对地址是一样的,如果一定要使用其它函数,则必须将函数体写入目标进程空间。
(2) 不能使用任何字符串常量,因为字符串常量是存放在PE文件里.data这个段里面的,函数
里保存的只是相对地址。
(3) 去掉编译器的/GZ编译选项,这个选项是用来Enable Stack Frame Run-Time Error
Checking。当这个选项打开时,编译器会在每个函数中加入一些代码,用来检验ESP在函数体中是
否被改变,但是这些检验函数的地址在不同PE文件中有可能是不一样的。 (4) 不得使用增量链接(incremental linking)。增量链接是编译器为了减少链接时间做的
处理,把函数体用一个JMP指令代替,这样就可以随意改变函数的内容,而不用修改CALL指令。
(5) 不要在函数体内使用超过4kb的局部变量。局部变量是存放在栈中的,例如下面这个函数
void Dummy(void) { BYTE var[256]; var[0] = 0; var[1] = 1; var[255] = 255;
}
在分配局部变量空间时是这样的 :00401000 push ebp
:00401001 mov ebp, esp
:00401003 sub esp, 00000100 ; change ESP as storage for ; local variables is needed :00401006 mov byte ptr [esp], 00 ; var[0] = 0; :0040100A mov byte ptr [esp+01], 01 ; var[1] = 1;
:0040100F mov byte ptr [esp+FF], FF ; var[255] = 255; :00401017 mov esp, ebp ; restore stack pointer :00401019 pop ebp :0040101A ret
但是当局部变量的大小超过4kb时,栈指针并不直接改版,而是调用另一个函数来分配内存,这个
函数有可能在不同进程中的地址不一样。
(6) 函数体内switch语句中的case不要超过3个,否则编译器会在PE文件中使用跳转表,而这
个跳转表有可能在目标进程中并不存在。 下面是一个无DLL注入的例子: //参数结构 ;
typedef struct _RemotePara{ PVOID dwMessageBox; wchar_t strMessageBox[12]; }RemotePara; // 远程线程执行体
DWORD __stdcall ThreadProc(RemotePara *Para) {
typedef int (/*__stdcall*/ *PMessageBox) ( HWND , LPCTSTR , LPCTSTR , UINT ); PMessageBox MessageBoxFunc = (PMessageBox)Para->dwMessageBox;
MessageBoxFunc(NULL, Para->strMessageBox, Para->strMessageBox, MB_OK); return 0 ; }
DWORD THREADSIZE=1024; DWORD pID = 4688; DWORD byte_write;
HANDLE hRemoteProcess,hThread;
RemotePara myRemotePara,*pRemotePara; void *pRemoteThread; HINSTANCE hUser32 ;
hRemoteProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,pID); if(!hRemoteProcess)return 0;
// 在远程进程地址空间分配虚拟内存
pRemoteThread = VirtualAllocEx(hRemoteProcess, 0, THREADSIZE, MEM_COMMIT |
MEM_RESERVE,PAGE_EXECUTE_READWRITE); if(!pRemoteThread)return 0;
// 将线程执行体ThreadProc写入远程进程
if(!WriteProcessMemory(hRemoteProcess, pRemoteThread, &ThreadProc, THREADSIZE,0))
return 0;
ZeroMemory(&myRemotePara,sizeof(RemotePara)); hUser32 = LoadLibrary(L\
myRemotePara.dwMessageBox = (PVOID)GetProcAddress(hUser32, \ wcscat(myRemotePara.strMessageBox,L\复制MessageBox函数的参数 //写进目标进程
pRemotePara =(RemotePara *)VirtualAllocEx (hRemoteProcess ,0,sizeof
(RemotePara),MEM_COMMIT,PAGE_READWRITE); if(!pRemotePara)return 0;
if(!WriteProcessMemory (hRemoteProcess ,pRemotePara,&myRemotePara,sizeof
myRemotePara,0))return 0; // 启动线程
hThread = CreateRemoteThread(hRemoteProcess ,0,0,(LPTHREAD_START_ROUTINE)
pRemoteThread ,pRemotePara,0,&byte_write); FreeLibrary(hUser32);
CloseHandle(hRemoteProcess);
第七种方法:
利用DLL劫持内存补丁技术注入
当一个可执行文件运行时,Windows加载器将可执行模块映射到进程的地址空间中,加载器分
析可执行模块的输入表,并设法找出任何需要的DLL,并将它们映射到进程的地址空间中。
由于输入表中只包含DLL名而没有它的路径名,因此加载程序必须在磁盘上搜索DLL文件。首先会
尝试从当前程序所在的目录加载DLL,如果没找到,则在Windows系统目录查找,最后是在环境变
量中列出的各个目录下查找。利用这个特点,先伪造一个系统同名的DLL,提供同样的输出表,每
个输出函数转向真正的系统DLL。程序调用系统DLL时会先调用当前目录下伪造的DLL,完成相关功
能后,再跳到系统DLL同名函数里执行。这个过程用个形象的词来描述就是系统DLL被劫持
(hijack)了。
示例DELPHI源码: Library USP10; uses
Windows, SysUtils, Classes;
{$R *.res}
ID:THandle;
ModHandle: Cardinal; POldLpkPresent: Pointer;
POldScriptApplyDigitSubstitution: Pointer; POldScriptApplyLogicalWidth: Pointer; POldScriptBreak: Pointer; POldScriptCPtoX: Pointer;
POldScriptCacheGetHeight: Pointer; POldScriptFreeCache: Pointer; POldScriptGetCMap: Pointer;
POldScriptGetFontProperties: Pointer; POldScriptGetGlyphABCWidth: Pointer; POldScriptGetLogicalWidths: Pointer; POldScriptGetProperties: Pointer; POldScriptIsComplex: Pointer; POldScriptItemize: Pointer; POldScriptJustify: Pointer; POldScriptLayout: Pointer; POldScriptPlace: Pointer;
POldScriptRecordDigitSubstitution: Pointer; POldScriptShape: Pointer;
POldScriptStringAnalyse: Pointer; POldScriptStringCPtoX: Pointer; POldScriptStringFree: Pointer;
POldScriptStringGetLogicalWidths: Pointer; POldScriptStringGetOrder: Pointer; POldScriptStringOut: Pointer; POldScriptStringValidate: Pointer; POldScriptStringXtoCP: Pointer; POldScriptString_pLogAttr: Pointer; POldScriptString_pSize: Pointer;
POldScriptString_pcOutChars: Pointer; POldScriptTextOut: Pointer; POldScriptXtoCP: Pointer; POldUspAllocCache: Pointer; POldUspAllocTemp: Pointer; POldUspFreeMem: Pointer;
procedure LpkPresent; asm jmp POldLpkPresent end;
procedure ScriptApplyDigitSubstitution; asm jmp POldScriptApplyDigitSubstitution end; procedure ScriptApplyLogicalWidth; asm jmp POldScriptApplyLogicalWidth end; procedure ScriptBreak; asm jmp POldScriptBreak end; procedure ScriptCPtoX; asm jmp POldScriptCPtoX end;
procedure ScriptCacheGetHeight; asm jmp POldScriptCacheGetHeight end; procedure ScriptFreeCache; asm jmp POldScriptFreeCache end; procedure ScriptGetCMap; asm jmp POldScriptGetCMap end;
procedure ScriptGetFontProperties; asm jmp POldScriptGetFontProperties end;
procedure ScriptGetGlyphABCWidth; asm jmp POldScriptGetGlyphABCWidth end; procedure ScriptGetLogicalWidths; asm jmp POldScriptGetLogicalWidths end; procedure ScriptGetProperties; asm jmp POldScriptGetProperties end; procedure ScriptIsComplex; asm jmp POldScriptIsComplex end; procedure ScriptItemize; asm jmp POldScriptItemize end; procedure ScriptJustify; asm jmp POldScriptJustify end; procedure ScriptLayout; asm jmp POldScriptLayout end; procedure ScriptPlace; asm jmp POldScriptPlace end;
procedure ScriptRecordDigitSubstitution; asm jmp POldScriptRecordDigitSubstitution end;
procedure ScriptShape; asm jmp POldScriptShape end;
procedure ScriptStringAnalyse; asm jmp POldScriptStringAnalyse end; procedure ScriptStringCPtoX; asm jmp POldScriptStringCPtoX end; procedure ScriptStringFree; asm jmp POldScriptStringFree end;
procedure ScriptStringGetLogicalWidths; asm jmp POldScriptStringGetLogicalWidths end; procedure ScriptStringGetOrder; asm jmp POldScriptStringGetOrder end; procedure ScriptStringOut; asm jmp POldScriptStringOut end;
procedure ScriptStringValidate; asm jmp POldScriptStringValidate end; procedure ScriptStringXtoCP; asm jmp POldScriptStringXtoCP end;
procedure ScriptString_pLogAttr; asm jmp POldScriptString_pLogAttr end;
搜索“diyifanwen.net”或“第一范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,第一范文网,提供最新小学教育DLL的11种注入方法 (6)全文阅读和word下载服务。
相关推荐: