当一个可执行文件运行时,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; procedure ScriptString_pSize; asm jmp POldScriptString_pSize end; procedure ScriptString_pcOutChars; asm jmp POldScriptString_pcOutChars end; procedure ScriptTextOut; asm jmp POldScriptTextOut end; procedure ScriptXtoCP; asm jmp POldScriptXtoCP end; procedure UspAllocCache; asm jmp POldUspAllocCache end; procedure UspAllocTemp; asm jmp POldUspAllocTemp end; procedure UspFreeMem; asm jmp POldUspFreeMem end; exports LpkPresent, ScriptApplyDigitSubstitution, ScriptApplyLogicalWidth, ScriptBreak, ScriptCPtoX, ScriptCacheGetHeight, ScriptFreeCache, ScriptGetCMap, ScriptGetFontProperties, ScriptGetGlyphABCWidth, ScriptGetLogicalWidths, ScriptGetProperties, ScriptIsComplex, ScriptItemize, ScriptJustify, ScriptLayout, ScriptPlace, ScriptRecordDigitSubstitution, ScriptShape, ScriptStringAnalyse, ScriptStringCPtoX, ScriptStringFree, ScriptStringGetLogicalWidths, ScriptStringGetOrder, ScriptStringOut, ScriptStringValidate, ScriptStringXtoCP, ScriptString_pLogAttr, ScriptString_pSize, ScriptString_pcOutChars, ScriptTextOut, ScriptXtoCP, UspAllocCache, UspAllocTemp, UspFreeMem; begin ModHandle:= LoadLibrary('C:/WINDOWS/system32/usp10.dll'); if ModHandle > 0 then begin POldLpkPresent:= GetProcAddress(ModHandle, 'LpkPresent'); POldScriptApplyDigitSubstitution:= GetProcAddress(ModHandle, 'ScriptApplyDigitSubstitution'); POldScriptApplyLogicalWidth:= GetProcAddress(ModHandle, 'ScriptApplyLogicalWidth'); POldScriptBreak:= GetProcAddress(ModHandle, 'ScriptBreak'); POldScriptCPtoX:= GetProcAddress(ModHandle, 'ScriptCPtoX'); POldScriptCacheGetHeight:= GetProcAddress(ModHandle, 'ScriptCacheGetHeight'); POldScriptFreeCache:= GetProcAddress(ModHandle, 'ScriptFreeCache'); POldScriptGetCMap:= GetProcAddress(ModHandle, 'ScriptGetCMap'); POldScriptGetFontProperties:= GetProcAddress(ModHandle, 'ScriptGetFontProperties'); POldScriptGetGlyphABCWidth:= GetProcAddress(ModHandle, 'ScriptGetGlyphABCWidth'); POldScriptGetLogicalWidths:= GetProcAddress(ModHandle, 'ScriptGetLogicalWidths'); POldScriptGetProperties:= GetProcAddress(ModHandle, 'ScriptGetProperties'); POldScriptIsComplex:= GetProcAddress(ModHandle, 'ScriptIsComplex'); POldScriptItemize:= GetProcAddress(ModHandle, 'ScriptItemize'); POldScriptJustify:= GetProcAddress(ModHandle, 'ScriptJustify'); POldScriptLayout:= GetProcAddress(ModHandle, 'ScriptLayout'); POldScriptPlace:= GetProcAddress(ModHandle, 'ScriptPlace'); POldScriptRecordDigitSubstitution:= GetProcAddress(ModHandle, 'ScriptRecordDigitSubstitution'); POldScriptShape:= GetProcAddress(ModHandle, 'ScriptShape'); POldScriptStringAnalyse:= GetProcAddress(ModHandle, 'ScriptStringAnalyse'); POldScriptStringCPtoX:= GetProcAddress(ModHandle, 'ScriptStringCPtoX'); POldScriptStringFree:= GetProcAddress(ModHandle, 'ScriptStringFree'); POldScriptStringGetLogicalWidths:= GetProcAddress(ModHandle, 'ScriptStringGetLogicalWidths'); POldScriptStringGetOrder:= GetProcAddress(ModHandle, 'ScriptStringGetOrder'); POldScriptStringOut:= GetProcAddress(ModHandle, 'ScriptStringOut'); POldScriptStringValidate:= GetProcAddress(ModHandle, 'ScriptStringValidate'); POldScriptStringXtoCP:= GetProcAddress(ModHandle, 'ScriptStringXtoCP'); POldScriptString_pLogAttr:= GetProcAddress(ModHandle, 'ScriptString_pLogAttr'); POldScriptString_pSize:= GetProcAddress(ModHandle, 'ScriptString_pSize'); POldScriptString_pcOutChars:= GetProcAddress(ModHandle, 'ScriptString_pcOutChars'); POldScriptTextOut:= GetProcAddress(ModHandle, 'ScriptTextOut'); POldScriptXtoCP:= GetProcAddress(ModHandle, 'ScriptXtoCP'); POldUspAllocCache:= GetProcAddress(ModHandle, 'UspAllocCache'); POldUspAllocTemp:= GetProcAddress(ModHandle, 'UspAllocTemp'); POldUspFreeMem:= GetProcAddress(ModHandle, 'UspFreeMem'); end; begin //添加自己的补丁内容! end; end.