0

Could someone helps me in porting this C++ function into Delphi?

sys is a class named TSystem.

SharedMem is a class named TVirtualMemory.

int Process::FixApi(dword FileHandler,image_import_descriptor* Imports,dword dllbase){
    image_import_by_name** names;                
    dword* pointers;                                                          
    if (Imports->original_first_thunk!=0){
       names=(image_import_by_name**)Imports->original_first_thunk;                                               
    }else{
          names=(image_import_by_name**)Imports->first_thunk;
    };
    names=(image_import_by_name**)((dword)names+FileHandler);
    pointers=(dword*)(Imports->first_thunk + FileHandler);
    if (Imports->first_thunk==0)return 0;                                          
    for (int i=0;i<200;i++){
        if (names[i]==0)break;
        if(!((dword)(names[i]->name+FileHandler) & 0x80000000)){
            dword s=(dword)names[i]->name;
            dword ptr=sys->GetAPI((char*)(s+FileHandler),dllbase);
            dword n=this->SharedMem->get_virtual_pointer(ptr);
            if (n!=0){
               ptr=n;
            }
            memcpy(&pointers[i],&ptr,4);
        }
    };
};

thank you

This is my attempt to convert the above code :

function FixApi(FileHandler: dword;
  Imports: Pimage_import_descriptor; dllbase: dword): Integer;
var
names:^image_import_by_name;
pointers:Pdword;
i:integer;
s,ptr,n:dword;
begin
if Imports^.original_first_thunk<>0 then
names:=Pointer(Imports^.original_first_thunk)
else
names:=Pointer(Imports^.first_thunk);

names:=Pointer(dword(names)+FileHandler);
pointers:=Pdword(Imports^.first_thunk+FileHandler);
if (Imports^.first_thunk=0)then result:=0;

for i:=0 to 200 do
begin
{
// i didn't get it 
if (names[i]==0)break;
if(!((dword)(names[i]->name+FileHandler) & 0x80000000)){
dword s=(dword)names[i]->name;
}
ptr:=sys.GetAPI(PChar(s+FileHandler),dllbase);
n:=SharedMem.get_virtual_pointer(ptr);
if n<>0 then
ptr:=n;

CopyMemory(@pointers[i],@ptr,4);

end;
end;
10
  • 1st time i tried but i was stuck in this : image_import_by_name** names; i mean the ( ** ) . if it was * i know it's a Pointer , but this (**) ? Commented Jan 7, 2012 at 12:07
  • That's a pointer to a pointer. I think you can't specify this type inline in delphi, but you need to define a PImage_import_by_name type. And then specify a pointer to this pointer type inline. Commented Jan 7, 2012 at 12:08
  • how it could be declared in delphi ? like this : var names:Pimage_import_by_name; Commented Jan 7, 2012 at 12:12
  • var names:Pimage_import_by_name^; or var names:PPimage_import_by_name; assuming you created the appropriate type definitions. Commented Jan 7, 2012 at 12:15
  • names=(image_import_by_name**)Imports->original_first_thunk; is this is the correct declaration : names:=Pimage_import_by_name(Imports.original_first_thunk); Commented Jan 7, 2012 at 12:18

2 Answers 2

4

Something like this (DWORD and PDWORD are defined in the Windows unit):

type
  PImageImportByName  = ^TImageImportByName;
  PPImageImportByName = ^PImageImportByName;

  PImageImportDescriptor = ^TImageImportDescriptor;

// Since the original code has no valuable return code, I changed it to a procedure
procedure FixApi(FileHandler: DWORD; Imports: PImageImportDescriptor; DllBase: DWORD);
var
  Names: PPImageImportByName;
  Pointers: PDWORD;
  S: DWORD;
  Ptr: DWORD;
  N: DWORD;
begin
  if Imports.FirstThunk = 0 then
    Exit;

  if Imports.OriginalFirstThunk <> 0 then
    Names := PPImageImportByName(Imports.OriginalFirstThunk)
  else
    Names := PPImageImportByName(Imports.FirstThunk);

  Names    := PPImageImportByName(DWORD(Names) + FileHandler);
  Pointers := PDWORD(Imports.FirstThunk + FileHandler);

  for I := 0 to 199 do begin
    if Names[I] = nil then
      Break;

    if (DWORD(Names[I].Name + FileHandler) and $80000000) = 0 then begin
      S   := DWORD(Names[I].Name);
      Ptr := Sys.GetApi(PChar(S + FileHandler), DllBase);
      N   := SharedMem.GetVirtualPointer(Ptr);
      if N <> 0 then begin
        Ptr := N;
      end;
      Move(Ptr, Pointers[I], 4); // I'm not sure about this part
    end;
  end;
end;

Edit: I fixed the condition in the line (DWORD(Names[I].Name + FileHandler) and $80000000) = 0.

Sign up to request clarification or add additional context in comments.

3 Comments

thank you < if Names[I] = nil then > i get an error here : Array type required .
You could declare PPimageImportByName = array[0..0] of PimageImportByName, this way Delphi will see the double pointer as an array of pointer (which it probably is in the original C/C++ code).
Be aware that array[0..0] is a common hack that can be used to tell the compiler that the code is a static array of unknown size. This is often used to interface with external code.
0

Try something like this:

uses
  ..., Windows;

type
  PPIMAGE_IMPORT_BY_NAME = ^PIMAGE_IMPORT_BY_NAME;

function Process.FixApi(FileHandler: DWORD; Imports: PIMAGE_IMPORT_DESCRIPTOR; dllbase: DWORD): Integer;
var
  names: PPIMAGE_IMPORT_BY_NAME;
  pointers: LPDWORD;
  i: Integer;
  s, ptr, n: DWORD;
begin
  Result := 0;
  if Imports^.original_first_thunk <> 0 then
    names := PPIMAGE_IMPORT_BY_NAME(Imports^.original_first_thunk)
  else
    names := PPIMAGE_IMPORT_BY_NAME(Imports^.first_thunk);
  names := PPIMAGE_IMPORT_BY_NAME(DWORD(names) + FileHandler);
  pointers := LPDWORD(Imports^.first_thunk + FileHandler); 
  if Imports^.first_thunk = 0 then Exit;
  for i := 0 to 199 do
  begin
    if names^ = nil then Break; 
    if (DWORD(names^^.name + FileHandler) and $80000000) = 0 then
    begin
      s := DWORD(names^^.name); 
      ptr := sys.GetAPI(PAnsiChar(s + FileHandler), dllbase); 
      n := Self.SharedMem.get_virtual_pointer(ptr); 
      if n <> 0 then
        ptr := n; 
      pointers^ := ptr;
    end;
    Inc(names);
    Inc(pointers); 
  end; 
end; 

3 Comments

many thanks for you all But why i get a compiler error : ' Array type required ' in if names[i] = ....;
You must be using a version of Delphi (which one exactly?) that does not support pointer arithmetic. I have updated my answer to tweak those lines accordingly.
Lebeau : I'm still with my OLD Delphi 7 friend .

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.