The closed source "Func-In" technique was was pioneered by p0ke (in Nidhogg Crypter) and shapeless (in Poison Ivy). This recreated, open source Delphi example details how to write functions to the resource section of your stub and then call that function from resources upon execution. This enables the user to keep the size of the final application down by only writing selected functions to the stub. Authors: Counterstrikewi, Abhe & Steve10120 Websites: delphibasics.info & ic0de.org Compiled: Delphi 2007, Delphi XE Slayer616 created his own func-in technology using shellcode: Builder: program Builder; //delphibasics.info & ic0de.org //Authors: cswi, abhe & steve10120 const 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. |
Delphi Basics - Free Delphi Source Code - Ultimate Programming Resource > Delphi Basics Counterstrikewi Releases >