Injection

Technical Discussions not Related Directly to MHS. For Example, Coding, Hex Editing, General Hacking, Etc.

Moderators: g3nuin3, SpeedWing, WhiteHat

Injection

Postby Sonic-Y3k » Thu Nov 19, 2009 8:17 pm

Hey Guys,
I've got the following problem and i'm hoping you can help me. During the last days i tried to build an delphi injector that injects a speedhack dll in a program. But unfortunately it doesn't work.

The dll itself seems to work, because i'm able to inject it through MHS.

Here are the facts:
- Windows 7 OS, UAC Disabled
- MHS: MHS5.2009
- Embarcadero RAD Studio 2010 (Delphi 2010)
- The Program (Game) I want to inject in: http://www.virtualskipper-game.com/vsk5/

Now comes the code part:
Speedhack.dll
Code: Select all
library speedhack;
uses
  SysUtils,
  Classes,
  speedhackunit in 'speedhackunit.pas';

{$R *.res}

begin
  acceleration := 500;
  sleeptime    :=   1;
  InitializeSpeedhack;
end.


speedhackunit.pas
Code: Select all
unit speedhackunit;

interface
uses windows,classes;

type TAPIInfo = record
  location: Pointer;
  Original: Array [0..4] of byte;
  Jump:     Array [0..4] of byte;
end;

type TTick=class(TThread)
  private
  public
    procedure Execute; override;
  end;

procedure InitializeSpeedhack;
procedure StopSpeedhack;

procedure GetTime; stdcall;
//function GetTime:dword; stdcall;
function NewQueryPerformanceCounter(var output: int64):BOOl; stdcall;
var CETick: dword;
    CETick64: int64;
    Ticker: TTick;

    PerformanceFrequency: int64;
    PerformanceFrequencyMS: int64;
    acceleration: single;
    sleeptime: dword;
    slow: boolean;
    tickerstopped: boolean;
    speedhackenabled: boolean;


    timeGetTimeInfo:TAPiInfo;
    getTickcountInfo: TAPIInfo;
    QueryPerformanceCounterInfo: TAPIInfo;
    winmmlib,kernel32lib: thandle;

implementation

procedure InitializeSpeedhack;
var op:dword;
begin
  cetick:=gettickcount;
  //change the gettickcount and timegettime functions so that they look at cetick
  if ticker<>nil then
  begin
    ticker.Terminate;
    stopspeedhack;
  end;
  ticker:=nil;


  winmmlib:=LoadLibrary('winmm.dll');
  if winmmlib<>0 then
  begin
    timeGetTimeInfo.location:=GetProcAddress(winmmlib,'timeGetTime');
    if VirtualProtect(timeGetTimeInfo.location,5,PAGE_EXECUTE_READWRITE,op) then
    begin
      timeGetTimeInfo.jump[0]:=$e9;
      pdword(@timeGetTimeInfo.jump[1])^:=dword(@GetTime)-dword(timeGetTimeInfo.location)-5;

      try
        asm
          //store original
          push edi
          push esi
          lea edi,timeGetTimeInfo.original[0]
          mov esi,timeGetTimeInfo.location
          movsd
          movsb

          //replace with jump
          lea esi,timeGetTimeInfo.jump[0]
          mov edi,timeGetTimeInfo.location
          movsd
          movsb

          pop esi
          pop edi
        end;
      except

      end;
    end;
  end;


  kernel32lib:=LoadLibrary('kernel32.dll');
  if kernel32lib<>0 then
  begin
    //gettickcount
    GetTickCountInfo.location:=GetProcAddress(kernel32lib,'GetTickCount');
    if VirtualProtect(GetTickCountInfo.location,5,PAGE_EXECUTE_READWRITE,op) then
    begin
      GetTickCountInfo.jump[0]:=$e9;
      pdword(@GetTickCountInfo.jump[1])^:=dword(@GetTime)-dword(GetTickCountInfo.location)-5;

      try
        asm
          //store original
          push edi
          push esi
          lea edi,GetTickCountInfo.original[0]
          mov esi,GetTickCountInfo.location
          movsd
          movsb

          //replace with jump
          lea esi,GetTickCountInfo.jump[0]
          mov edi,GetTickCountInfo.location
          movsd
          movsb

          pop esi
          pop edi
        end;
      except

      end;
    end;


    //QueryPerformanceCounter
    if QueryPerformanceFrequency(PerformanceFrequency) then
    begin
      QueryPerformanceCounter(CETick64);
      PerformanceFrequencyMS:=PerformanceFrequency div 1000;

      //there is a high performance counter
      QueryPerformanceCounterInfo.location:=GetProcAddress(kernel32lib,'QueryPerformanceCounter');
      if VirtualProtect(QueryPerformanceCounterInfo.location,5,PAGE_EXECUTE_READWRITE,op) then
      begin
        QueryPerformanceCounterInfo.jump[0]:=$e9;
        pdword(@QueryPerformanceCounterInfo.jump[1])^:=dword(@NewQueryPerformanceCounter)-dword(QueryPerformanceCounterInfo.location)-5;

        try
          asm
            //store original
            push edi
            push esi
            lea edi,QueryPerformanceCounterInfo.original[0]
            mov esi,QueryPerformanceCounterInfo.location
            movsd
            movsb

            //replace with jump
            lea esi,QueryPerformanceCounterInfo.jump[0]
            mov edi,QueryPerformanceCounterInfo.location
            movsd
            movsb

            pop esi
            pop edi
          end;
        except

        end;
      end;
    end;
  end;

  speedhackenabled:=true;

  if ticker=nil then ticker:=TTick.Create(false);
end;

procedure StopSpeedhack;
begin
  if not speedhackenabled then exit;

  speedhackenableD:=false;

  try
    asm
      lea esi,timeGetTimeInfo.original[0]
      mov edi,timeGetTimeInfo.location
      movsd
      movsb
    end;
  except

  end;

  try
    asm
      lea esi,GetTickCountInfo.original[0]
      mov edi,GetTickCountInfo.location
      movsd
      movsb
    end;
  except

  end;

  try
    asm
      lea esi,QueryPerformanceCounterInfo.original[0]
      mov edi,QueryPerformanceCounterInfo.location
      movsd
      movsb
    end;
  except

  end;



  FreeLibrary(winmmlib);
  FreeLibrary(kernel32lib);
  winmmlib:=0;
  kernel32lib:=0;
  if ticker<>nil then ticker.terminate;
  ticker:=nil;
end;


procedure GetTime; stdcall;
asm
  mov eax,[CETick]
  ret
end;

{function GetTime:dword; stdcall;
begin
  result:=CETick;
end;}

function NewQueryPerformanceCounter(var output: int64):BOOl; stdcall;
begin
  output:=cetick64;
  result:=true;
end;

procedure TTick.Execute;
begin
  tickerstopped:=false;
  freeonterminate:=true;
  priority:=tpTimeCritical; //if not a thread with higher priority will prevent the timer from running
  while not terminated do
  begin
    inc(cetick64,trunc(acceleration*(PerformanceFrequency / (1000 / sleeptime))) );
    inc(cetick,trunc(sleeptime*acceleration));
    sleep(sleeptime);
  end;
  tickerstopped:=true;
end;

initialization
  acceleration:=1.8;
  sleeptime:=10;
  InitializeSpeedhack;

end.


Now the Injection Tool:
Code: Select all
program ProjectInject;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  windows,
  psapi,
  tlhelp32,
  inifiles,
  speedhackunit in 'speedhackunit.pas', Messages, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TUI = class(tthread)
  public
    procedure execute; override;
  end;

var
  WName,PName,DName:string;
  DLLLocation:string;
  ProcessId:DWORD;
  sui: tui;

procedure Tui.Execute;
begin
  //
end;

procedure PhraseINI();
var
  IniFile:TIniFile;
begin
  if FileExists(GetCurrentDir + '\Injector.ini') then
  begin
    IniFile:=TIniFile.Create(GetCurrentDir + '\Injector.ini');
    WName:=IniFile.ReadString('DLL Injector','Window','');
    PName:=IniFile.ReadString('DLL Injector','Target','notepad.exe');
    DName:=IniFile.ReadString('DLL Injector','DLL','MessageBox.dll');
  end
  else
  begin
    IniFile:=TIniFile.Create(GetCurrentDir + '\Injector.ini');
    IniFile.WriteString('DLL Injector','Window','Untitled - Notepad');
    IniFile.WriteString('DLL Injector','Target','notepad.exe');
    IniFile.WriteString('DLL Injector','DLL','MessageBox.dll');
    PhraseINI();
  end;
end;

procedure GetPID();
var
  TempSnapshot:THandle;
  Process32:TProcessEntry32;
  Name: HWND;
begin
  Name      :=  FindWindow('PName',nil);
  ProcessId :=  GetWindowThreadProcessId(Name);
  {while (ProcessId=0) do
  begin
    TempSnapshot:=CreateToolhelp32Snapshot(TH32CS_SNAPALL,0);
    Process32First(TempSnapshot,Process32);
    while Process32Next(TempSnapshot,Process32) do
      begin
        if Process32.szExeFile = PName then
            ProcessId:=Process32.th32ProcessID;
      end;
    CloseHandle(TempSnapshot);
  end;}
  //ProcessId :=  4728;
end;

procedure InjectDLL();
var
  Process:THandle;
  TempHandle:THandle;
  AllocatedRegion:pointer;
  Empty:DWORD;
  NumberOfBytesWritten:Cardinal;
begin
  Process:=OpenProcess(PROCESS_ALL_ACCESS,False,ProcessId);
  AllocatedRegion:=VirtualAllocEx(Process,NIL,length(DLLLocation),MEM_COMMIT,PAGE_EXECUTE_READWRITE);
  WriteProcessMemory(Process,AllocatedRegion,pchar(DLLLocation),length(DLLLocation),NumberOfBytesWritten);
  if WName='' then
    sleep(750)
  else
    while FindWindow(nil,pchar(WName))=0 do
      sleep(10);
  TempHandle:=CreateRemoteThread(Process,nil,0,GetProcAddress(GetModuleHandle('kernel32.dll'),'LoadLibraryA'),AllocatedRegion,0,Empty);
  WaitForSingleObject(TempHandle,INFINITE);
  CloseHandle(TempHandle);
end;

begin
  PhraseINI();
  Writeln('- DLL Injector -'+#$0A+#$0D+'----------------');
  DLLLocation:=GetCurrentDir()+'\'+DName;
  if not FileExists(DLLLocation) then
  begin
    Writeln('Unable to locate the DLL');
    sleep(7000);
    exitprocess(0);
  end;
  Writeln('Waiting for process: '+PName);
  GetPID();
  Writeln(' - Process found'+#$0A+#$0D);
  Writeln('Injecting '+DName+' into '+PName);
  InjectDLL();
  Writeln(' - DLL injected');
  sui:=tui.create(false);
  acceleration := 500;
  sleeptime    :=   1;
  sleep(7000);
end.


Sorry for my bad english,
Sonic-Y3k
Attachments
Injector.rar
Source Code of the command line tool to inject the dll
(2.98 KiB) Downloaded 596 times
Speedhack.rar
the source code of the dll
(114.58 KiB) Downloaded 807 times
Sonic-Y3k
I Have A Question
 
Posts: 1
Joined: Thu Nov 19, 2009 7:54 pm

Re: Injection

Postby L. Spiro » Thu Nov 19, 2009 9:13 pm

I do not know Delphi and have a hard time reading your code.

Ensure that the string you write to the target process is NULL-terminated. Under normal circumstances a string’s length does not include the terminating NULL character, meaning you need to write length + 1.

Ensure that you have opened the target process with the sufficient privileges and that the entire opening process succeeds.


L. Spiro
Our songs remind you of songs you’ve never heard.
User avatar
L. Spiro
L. Spiro
 
Posts: 3129
Joined: Mon Jul 17, 2006 10:14 pm
Location: Tokyo, Japan

Re: Injection

Postby SztringzS » Fri Nov 20, 2009 11:38 am

L. Spiro wrote:I do not know Delphi and have a hard time reading your code.

Ensure that the string you write to the target process is NULL-terminated. Under normal circumstances a string’s length does not include the terminating NULL character, meaning you need to write length + 1.

Ensure that you have opened the target process with the sufficient privileges and that the entire opening process succeeds.


L. Spiro


ur so smart..

im jealous
Kind of ironic huh? Cracking a patcher. Maybe if I get some free time, I'll patch this patcher and then make a patcher with this patcher to patch your patcher!

check out my colorful Thread ! - http://memoryhacking.com/forums/viewtopic.php?f=43&t=6382

Image
SztringzS
I Know My Poop
 
Posts: 467
Joined: Tue Jul 28, 2009 8:40 am
Location: Pluto :D


Return to Technical Unrelated

Who is online

Users browsing this forum: No registered users and 0 guests