Func-In Delphi Example

posted 22 Dec 2010, 11:18 by Delphi Basics   [ updated 23 Dec 2010, 14:39 ]
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,
23 Dec 2010, 14:40
Comments