Jump to content
Tuts 4 You

[Delphi] Store Function in Resource Section of Executable


counterstrikewi

Recommended Posts

counterstrikewi
Posted (edited)

hi,

I am trying to store a custom procedure within the resource section of my executable.

Then, I hope to call that procedure from resource.

I have a basic example working and I have posted full delphi source code for this example.

However, there are limitations.

I am having trouble retrieving return values from Windows API.

As you can see in the code below, if you compile both executables with the comment in the builder intact, then run the builder, next the stub, it works perfectly. However, if you remove the comment in the builder to assign a local variable to the result of a Windows API, then run the builder, next the stub, it results in an error :(

Builder:


program Builder;
//ic0de.org
//cswi <3 abhe
{$APPTYPE CONSOLE}uses
Windows;const
cFuncIn : PWideChar = 'FUNCIN';type
TMessageBoxA = function (hWnd: Cardinal; lpText, lpCaption: PAnsiChar; uType: LongWord): LongWord; stdcall;
TGetProcAddress = function (hModule: Cardinal; lpProcName: pAnsiChar): Pointer; stdcall;
TLoadLibraryA = function(lpLibFileName: PAnsiChar): Cardinal; stdcall; TFuncInRecord = Record
xMessageBoxA : TMessageBoxA;
xGetProcAddress : TGetProcAddress;
xLoadLibraryA : TLoadLibraryA;
gpUser32 : pAnsiChar;
gpMessageBoxA : pAnsiChar;
gpString : pAnsiChar;
end;
PFuncInRecord = ^TFuncInRecord;procedure FuncIn(pData : PFuncInRecord; lpTitle, lpMessage : pAnsiChar);
var
lhKernel : Cardinal;
lpString : pAnsiChar;
dwResult : LongWord;
begin
with pData^ do
begin
lpString := gpString;
{dwResult := }xMessageBoxA(0, lpString, lpTitle, MB_YESNO);
end;
end;Function WriteResData(pFile: pointer; Size: integer; pwName: pWideChar):Boolean;
const
pwServerFile : PWideChar = 'Stub.exe' ;
var
hResourceHandle: THandle;
begin
hResourceHandle := BeginUpdateResourceW(pwServerFile, False);
Result := UpdateResourceW(hResourceHandle, MakeIntResourceW(10), pwName, 0, pFile, Size);
EndUpdateResourceW(hResourceHandle, False);
end;function SizeOfProc(pAddr: pointer): Cardinal;
var dwSize: Cardinal;
begin
dwSize := 0;
repeat
inc(dwSize);
until PByte(Cardinal(pAddr)+dwSize-1)^ = $C3;
Result := dwSize;
end;begin
WriteResData(@FuncIn, SizeOfProc(@FuncIn), cFuncIn);
end.

Stub:


//ic0de.org
program Stub;{$APPTYPE CONSOLE}uses
Windows;const
cFuncIn : PWideChar = 'FUNCIN';type
TMessageBoxA = function (hWnd: Cardinal; lpText, lpCaption: PAnsiChar; uType: LongWord): LongWord; stdcall;
TGetProcAddress = function (hModule: Cardinal; lpProcName: pAnsiChar): Pointer; stdcall;
TLoadLibraryA = function(lpLibFileName: PAnsiChar): Cardinal; stdcall; TFuncInRecord = Record
xMessageBoxA : TMessageBoxA;
xGetProcAddress : TGetProcAddress;
xLoadLibraryA : TLoadLibraryA;
gpUser32 : pAnsiChar;
gpMessageBoxA : pAnsiChar;
gpString : pAnsiChar;
end;
PFuncInRecord = ^TFuncInRecord; TFuncIn = procedure(pData : PFuncInRecord; lpTitle, lpMessage : pAnsiChar);procedure ResGet(ResName: pwidechar; var data : pointer; var Size:dword);
var
ResSrc: hRSrc;
ResGlobal: hGlobal;
begin
ResSrc := FindResourceW(hInstance, ResName, MakeIntResourceW(10));
ResGlobal := LoadResource(hInstance, ResSrc);
data := LockResource(ResGlobal);
Size := SizeofResource(hInstance, ResSrc);
end;var
FuncIn : TFuncIn;
pResource : Pointer;
dwResourceSize :dword;
AFuncInRecord : TFuncInRecord;
begin
AFuncInRecord.xMessageBoxA := @MessageBoxA;
AFuncInRecord.xGetProcAddress := @GetProcAddress;
AFuncInRecord.xLoadLibraryA := @LoadLibraryA;
AFuncInRecord.gpUser32 := 'user32.dll';
AFuncInRecord.gpMessageBoxA := 'MessageBoxA';
AFuncInRecord.gpString := 'Test';
ResGet(cFuncIn, pResource, dwResourceSize);
CopyMemory(@FuncIn, pResource, dwResourceSize);
FuncIn(@AFuncInRecord,'Title','Caption');
end.

I look forward to reading your responses.

Thank you

Edited by counterstrikewi
counterstrikewi
Posted

Completed; although if you have something to criticize or add, i would love to hear your comment.

Authors: Counterstrikewi, Abhe & Steve10120

Websites: delphibasics.info & ic0de.org

Compiled: Delphi 2007

http://www.delphibasics.info/home/delphibasicscounterstrikewireleases/func-indelphiexample

Builder:


program Builder;
//delphibasics.info & ic0de.org
//cswi <3 abhe & steve10120
{$APPTYPE CONSOLE}uses
Windows;const
cFuncIn : PWideChar = 'FUNCIN';type
TGetProcAddress = function (hModule: Cardinal; lpProcName: pAnsiChar): Pointer; stdcall;
TLoadLibraryA = function(lpLibFileName: PAnsiChar): Cardinal; stdcall; TFuncInRecord = Record
xGetProcAddress : TGetProcAddress;
xLoadLibraryA : TLoadLibraryA;
gpUser32 : pAnsiChar;
gpMessageBoxA : pAnsiChar;
gpString : pAnsiChar;
end;
PFuncInRecord = ^TFuncInRecord;procedure FuncIn(pData : PFuncInRecord; lpTitle, lpMessage : pAnsiChar);
type
TMessageBoxA = function (hWnd: Cardinal; lpText, lpCaption: PAnsiChar; uType: LongWord): LongWord; stdcall;
var
xMessageBoxA : TMessageBoxA;
lhKernel : Cardinal;
lpString : pAnsiChar;
dwResult : LongWord;
begin
with pData^ do
begin
lpString := gpString;
lhKernel := xLoadLibraryA(gpUser32);
@xMessageBoxA := xGetProcAddress(lhKernel, gpMessageBoxA);
if Assigned(xMessageBoxA) then
begin
dwResult := xMessageBoxA(0, lpString, lpTitle, MB_YESNO);
if dwResult = 6 then
xMessageBoxA(0, lpString, lpTitle, MB_YESNO);
end;
end;
end;Function WriteResData(pFile: pointer; Size: integer; pwName: pWideChar):Boolean;
const
pwServerFile : PWideChar = 'Stub.exe' ;
var
hResourceHandle: THandle;
begin
hResourceHandle := BeginUpdateResourceW(pwServerFile, False);
Result := UpdateResourceW(hResourceHandle, MakeIntResourceW(10), pwName, 0, pFile, Size);
EndUpdateResourceW(hResourceHandle, False);
end;function SizeOfProc(pAddr: pointer): Cardinal;
var dwSize: Cardinal;
begin
dwSize := 0;
repeat
inc(dwSize);
until PByte(Cardinal(pAddr)+dwSize-1)^ = $C3;
Result := dwSize;
end;begin
WriteResData(@FuncIn, SizeOfProc(@FuncIn), cFuncIn);
end.

Stub:


program Stub;{$APPTYPE CONSOLE}uses
Windows;const
cFuncIn : PWideChar = 'FUNCIN';type
TGetProcAddress = function (hModule: Cardinal; lpProcName: pAnsiChar): Pointer; stdcall;
TLoadLibraryA = function(lpLibFileName: PAnsiChar): Cardinal; stdcall;
TFuncInRecord = Record
xGetProcAddress : TGetProcAddress;
xLoadLibraryA : TLoadLibraryA;
gpUser32 : pAnsiChar;
gpMessageBoxA : pAnsiChar;
gpString : pAnsiChar;
end;
PFuncInRecord = ^TFuncInRecord; TFuncIn = procedure(pData : PFuncInRecord; lpTitle, lpMessage : pAnsiChar);
PFuncIn = ^TFuncIn;procedure ResGet(ResName: pwidechar; var data : pointer; var Size:dword);
var
ResSrc: hRSrc;
ResGlobal: hGlobal;
begin
ResSrc := FindResourceW(hInstance, ResName, MakeIntResourceW(10));
ResGlobal := LoadResource(hInstance, ResSrc);
data := LockResource(ResGlobal);
Size := SizeofResource(hInstance, ResSrc);
end;var
FuncInCall: TFuncIn;
FuncIn : PFuncIn;
pResource : Pointer;
dwResourceSize :dword;
AFuncInRecord : TFuncInRecord;
begin
AFuncInRecord.xGetProcAddress := @GetProcAddress;
AFuncInRecord.xLoadLibraryA := @LoadLibraryA;
AFuncInRecord.gpUser32 := 'user32.dll';
AFuncInRecord.gpMessageBoxA := 'MessageBoxA';
AFuncInRecord.gpString := 'Test';
ResGet(cFuncIn, pResource, dwResourceSize);
FuncIn := VirtualAlloc(nil, dwResourceSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
CopyMemory(FuncIn, pResource, dwResourceSize);
FuncInCall := TFuncIn(DWORD(FuncIn));
FuncInCall(@AFuncInRecord,'Title','Caption');
VirtualFree(FuncIn, 0, MEM_RELEASE);
end.

B)

counterstrikewi
Posted

Updated:
/>http://www.delphibasics.info/home/delphibasicscounterstrikewireleases/func-indelphiexample

Builder:

program Builder;
//delphibasics.info & ic0de.org
//Authors: cswi, abhe & steve10120const
kernel32 = 'kernel32.dll';
MB_YESNO = 4;
MB_OK = 0;type
PByte = ^Byte;function BeginUpdateResourceW(pFileName: PWideChar; bDeleteExistingResources: Boolean): Cardinal; stdcall; external kernel32 name 'BeginUpdateResourceW';
function UpdateResourceW(hUpdate: Cardinal; lpType, lpName: PWideChar; wLanguage: Word; lpData: Pointer; cbData: LongWord): Boolean; stdcall; external kernel32 name 'UpdateResourceW';
function EndUpdateResourceW(hUpdate: Cardinal; fDiscard: Boolean): Boolean; stdcall; external kernel32 name 'EndUpdateResourceW';const
cFuncIn : PWideChar = 'FUNCIN';type
TGetProcAddress = function (hModule: Cardinal; lpProcName: pAnsiChar): Pointer; stdcall;
TLoadLibraryA = function(lpLibFileName: PAnsiChar): Cardinal; stdcall;
TFuncInRecord = Record
xGetProcAddress : TGetProcAddress;
xLoadLibraryA : TLoadLibraryA;
end;
PFuncInRecord = ^TFuncInRecord;procedure FuncIn(AFuncInRecord : PFuncInRecord; lpText, lpCaption : pAnsiChar);
type
TMessageBoxA = function (hWnd: Cardinal; lpText, lpCaption: PAnsiChar; uType: LongWord): LongWord; stdcall;
var
szUser32 : array[0..6] of AnsiChar;
szMessageBoxA : array[0..11] of AnsiChar;
xMessageBoxA : TMessageBoxA;
dwResult : LongWord;
begin
szUser32[0] := 'U';
szUser32[1] := 's';
szUser32[2] := 'e';
szUser32[3] := 'r';
szUser32[4] := '3';
szUser32[5] := '2';
szUser32[6] := #0;
szMessageBoxA[0] := 'M';
szMessageBoxA[1] := 'e';
szMessageBoxA[2] := 's';
szMessageBoxA[3] := 's';
szMessageBoxA[4] := 'a';
szMessageBoxA[5] := 'g';
szMessageBoxA[6] := 'e';
szMessageBoxA[7] := 'B';
szMessageBoxA[8] := 'o';
szMessageBoxA[9] := 'x';
szMessageBoxA[10] := 'A';
szMessageBoxA[11] := #0;
with AFuncInRecord^ do
begin
@xMessageBoxA := xGetProcAddress(xLoadLibraryA(szUser32), szMessageBoxA);
if Assigned(xMessageBoxA) then
begin
dwResult := xMessageBoxA(0, lpText, lpCaption, MB_YESNO);
if dwResult = 6 then
xMessageBoxA(0, lpText, lpCaption, MB_OK);
end;
end;
end;Function WriteResData(pFile: pointer; Size: integer; pwName: pWideChar):Boolean;
const
pwServerFile : PWideChar = 'Stub.exe' ;
var
hResourceHandle: Cardinal;
begin
hResourceHandle := BeginUpdateResourceW(pwServerFile, False);
Result := UpdateResourceW(hResourceHandle, PWideChar(10), pwName, 0, pFile, Size);
EndUpdateResourceW(hResourceHandle, False);
end;function SizeOfProc(pAddr: pointer): Cardinal;
var dwSize: Cardinal;
begin
dwSize := 0;
repeat
inc(dwSize);
until PByte(Cardinal(pAddr)+dwSize-1)^ = $C3;
Result := dwSize;
end;begin
WriteResData(@FuncIn, SizeOfProc(@FuncIn), cFuncIn);
WriteResData(nil, 0, 'PACKAGEINFO');
WriteResData(nil, 0, 'DVCLAL');
end.

Stub:


program Stub;const
kernel32 = 'kernel32.dll';
MEM_COMMIT = $1000;
PAGE_EXECUTE_READWRITE = $40;
MEM_RELEASE = $8000;function GetProcAddress(hModule: Cardinal; lpProcName: PAnsiChar): Pointer; stdcall; external kernel32 name 'GetProcAddress';
function LoadLibraryA(lpLibFileName: PAnsiChar): Cardinal; stdcall; external kernel32 name 'LoadLibraryA';
function FindResourceW(hModule: Cardinal; lpName, lpType: PWideChar): Cardinal; stdcall; external kernel32 name 'FindResourceW';
function LoadResource(hModule: Cardinal; hResInfo: Cardinal): Cardinal; stdcall; external kernel32 name 'LoadResource';
function SizeofResource(hModule: Cardinal; hResInfo: Cardinal): LongWord; stdcall; external kernel32 name 'SizeofResource';
function VirtualAlloc(lpvAddress: Pointer; dwSize, flAllocationType, flProtect: LongWord): Pointer; stdcall; external kernel32 name 'VirtualAlloc';
function VirtualFree(lpAddress: Pointer; dwSize, dwFreeType: LongWord): Boolean; stdcall; external kernel32 name 'VirtualFree';const
cFuncIn : PWideChar = 'FUNCIN';type
TGetProcAddress = function (hModule: Cardinal; lpProcName: pAnsiChar): Pointer; stdcall;
TLoadLibraryA = function(lpLibFileName: PAnsiChar): Cardinal; stdcall;
TFuncInRecord = Record
xGetProcAddress : TGetProcAddress;
xLoadLibraryA : TLoadLibraryA;
end;
PFuncInRecord = ^TFuncInRecord; PFuncIn = ^TFuncIn;
TFuncIn = procedure(pData : PFuncInRecord; lpTitle, lpMessage : pAnsiChar);procedure ResGet(ResName: pwidechar; var data : pointer; var Size:LongWord);
var
ResSrc: Cardinal;
ResGlobal: Cardinal;
begin
ResSrc := FindResourceW(0, ResName, PWideChar(10));
ResGlobal := LoadResource(0, ResSrc);
Data := Pointer(ResGlobal);
Size := SizeofResource(0, ResSrc);
end;procedure CopyMemory(Destination, Source:Pointer; dwSize:LongWord);
asm
PUSH ECX
PUSH ESI
PUSH EDI
MOV EDI, Destination
MOV ESI, Source
MOV ECX, dwSize
REP MOVSB
POP EDI
POP ESI
POP ECX
end;var
FuncIn : TFuncIn;
pResource : Pointer;
dwResourceSize : LongWord;
AFuncInRecord : TFuncInRecord;
begin
AFuncInRecord.xGetProcAddress := @GetProcAddress;
AFuncInRecord.xLoadLibraryA := @LoadLibraryA;
ResGet(cFuncIn, pResource, dwResourceSize);
FuncIn := VirtualAlloc(nil, dwResourceSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
CopyMemory(@FuncIn, pResource, dwResourceSize);
FuncIn(@AFuncInRecord,'cswi <3 abhe & steve10120', '<3 p0ke');
VirtualFree(@FuncIn, 0, MEM_RELEASE);
end.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...