1

I need to convert this C-Code to Delphi-Code and because my Delphi-Knowledge is not good enough I need your help!

My main problem is, that I don't know how to cast pointers / calculate with pointers in Delphi.

Of course i tried to convert it and for whoever is familiar with both languages should this be easy to do :)

Original code (C):

void* GetPayloadExportAddr( LPCWSTR lpPath, HMODULE hPayloadBase, LPCSTR lpFunctionName ) {
  // Load payload in our own virtual address space
  HMODULE hLoaded = LoadLibrary( lpPath );

  if( hLoaded == NULL ) {
    return NULL;
  } else {
    void* lpFunc   = GetProcAddress( hLoaded, lpFunctionName );
    DWORD dwOffset = (char*)lpFunc - (char*)hLoaded;

    FreeLibrary( hLoaded );
    return (DWORD)hPayloadBase + dwOffset;
  }
}

and

BOOL InitPayload( HANDLE hProcess, LPCWSTR lpPath, HMODULE hPayloadBase, HWND hwndDlg ) {
  void* lpInit = GetPayloadExportAddr( lpPath, hPayloadBase, "Init" );
  if( lpInit == NULL ) {
    return FALSE;
  } else {
    HANDLE hThread = CreateRemoteThread( hProcess, NULL, 0,
        lpInit, hwndDlg, 0, NULL );

    if( hThread == NULL ) {
      return FALSE;
    } else {
      CloseHandle( hThread );
    }
  }

And the partally converted Delphicode:

function GetPayloadExportAddr( lpPath: LPCWSTR; hPayloadBase: HMODULE; lpFunctionName: LPCWSTR) : Pointer;
var
  hLoaded: HMODULE;
  lpFunc: pointer;
  dwOffset: DWORD;
begin
   hLoaded := LoadLibrary( lpPath );

  if( hLoaded = 0 ) then
  begin
    Result := 0;
  end
  else
  begin
    lpFunc   := GetProcAddress( hLoaded, lpFunctionName );
    dwOffset := DWORD(PCHAR(lpFunc) - PCHAR(hLoaded));

    FreeLibrary( hLoaded );
    Result := PDWORD(DWORD(hPayloadBase) + dwOffset);
  end;
end;

and

procedure CallStopHack( hProcess: THandle; lpPath: LPCWSTR; hPayloadBase: HMODULE);
var
  lpInit : Pointer;
  hThread: THandle;
  bla:Cardinal;
begin
  lpInit := GetPayloadExportAddr(lpPath, hPayloadBase, 'StopSpeedhack');
  if( lpInit = nil ) then
  begin
    Exit;
  end
  else
  begin
     hThread := CreateRemoteThread( hProcess, nil, 0,
        lpInit, 0, 0, bla);

    if( hThread = 0 ) then
    begin
      Exit;
    end
    else
    begin
      CloseHandle( hThread );
    end;
  end;
end;

I assume that I messed up with the PDWORD()-Cast etc. I'm sorry but I don't know how to cast it correctly.

Thanks in advance! Regards

2 Answers 2

2

This should do:

dwOffset := DWORD(lpFunc) - hLoaded;

lpFunc is already a pointer and all you want is the address, hLoaded is already a NativeUint.

and

Result := Ptr(hPayloadBase + dwOffset);
Sign up to request clarification or add additional context in comments.

Comments

1

I see a few problems. LPCWSTR and LPCSTR are not the same. The first translates to PWideChar, while the second finally translates to PAnsiChar (or MarshaledAString, which is the same).

Also, if you are using Delphi 2009 or higher, you should not use PChar to cast for pointer math. Use either PByte or PAnsiChar, as these are single-byte types.

Note, however, that in Delphi, handles are integral types already, so there is no need to cast them at all:

dwOffset := NativeUInt(lpFunc) - hLoaded;

And later on:

Result := Pointer(hPayloadBase + dwOffset);

Note that I find code that tries to read an offset by subtracting a handle from a pointer (and then uses that offset to add to another handle) rather suspicious. It may work, but it looks like a terrible hack to me.

22 Comments

It's not suspicious in the slightest. It is explicitly documented than an HMODULE is the base address of the module.
Handles are supposed to be opaque types. If (it is documented that) you can treat a handle like a pointer, it is not a handle anymore.
That's a naive view. An HMODULE is the base address. That's the beginning and end of it. It uniquely identifies a module because two modules cannot exist at the same address.
Abstraction is not a naive view at all. Handles are there so that pointers are treated like opaque types, that only have meaning to the implementer.
Abstraction is indeed not a naive view point. However, treating something that is concrete as if it were abstract is certainly not useful. You need to update your belief as to what an HMODULE really is. It is more than you think it is. You can treat it as a unique handle to a module. And you can treat it as the base address of that module.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.