converting a c++ pointer cast to delphi - delphi

actually i am converting a c++ code to delphi, but i have problem to translate this line
PIMAGE_NT_HEADERS header = (BYTE *)lib + ((PIMAGE_DOS_HEADER)lib)->e_lfanew;
to delphi (this is my result at the moment)
var
lib : THandle;
header : PImageNtHeaders;
begin
//....
//.....
header := Pointer(PByte(lib) + PImageDosHeader(lib)._lfanew);
end;
but the compiler gives me this message operator not applicable to this operand type
can you help me to translate this line.

header := Pointer(Integer(PByte(lib)) + PImageDosHeader(lib)._lfanew);

You might be able to sidestep a lot of this. If you're looking for PE image header routines, look up the ImageHlp unit from the RTL, and the JclPeImage unit from the JCL. They've got lots of prebuilt code to make image and image header header work easier.

the _lfanew member is most likely an offset so it needs to be an integer or DWORD instead of a pointer. Just guessing as I don't use Delhpi but have you tried :-
header := Pointer(PByte(lib) + (DWORD)(PImageDosHeader(lib)._lfanew));
A web search came up with the following : http://www.cheesydoodle.com/?p=175
This code is Delphi based and is using the same library you are. You will most likely find a solution hidden in this code listing on CheesyDoodle.

Pointer arithmetic is much more limited in delphi, and direct addition is not allowed. You'll have to use the Inc function on your pointers.
example(source ):
program PointerArithmetic;
{$APPTYPE CONSOLE}
uses
SysUtils;
procedureWritePointer(P: PDouble);
begin
Writeln(Format('%8p', [P]));
end;
var
P: PDouble;
begin
P := Pointer($50000);
WritePointer(P);
Inc(P); // 00050008 = 00050000 + 1*SizeOf(Double)
WritePointer(P);
Inc(P, 6); // 00050038 = 00050000 + 7*Sizeof(Double)
WritePointer(P);
Dec(P, 4); // 00050018 = 00050000 + 3*Sizeof(Double)
WritePointer(P);
Readln;
end.

What you are working on is called RVA (Relative Virtual Address). Basic formula is
Address = Base + Displacement. Naturally, Address and Base are untyped pointers while Displacement is signed integer. Object Pascal disallows pointer arithmetics, so typecasting is required.
So:
var
Address, Base: Pointer;
Displacement: Integer;
{ ... }
Address := Pointer(Cardinal(Base) + Displacement);
{ or, in your case }
var
Module: HMODULE; { opaque type designates module handle and equals to load address }
NTHeaders: PImageNtHeaders;
begin
NTHeaders := Pointer(Cardinal(Module) + PImageDosHeader(Module)^._lfanew);
if NTHeaders^.Signature = ......

I don't work in Delphi day-to-day, but I suspect the error is due to one of two things:
Pointer math is not enabled. Delphi, by default, does not allow you to to C-style pointer manipulation, eg adding a number to a pointer to get another pointer - remember Delphi is a 'safe' language. To enable this, turn on pointer math using the {$POINTERMATH ON} directive. This forum posting has some more info too.
This is the bit I can't remember because it's been a while: You may not be able to add pointers of different types - remember the size of what the pointer points to is different. Without knowing what _lfanew is I can't give you more information. If this is the case, get everything in bytes and add those.
You may want to use the Inc function too, to convert your code to be more Delphi-like. Inc will increment a typed pointer by the size of the structure that pointer points to, not by one byte. Pointer math generally is not quite C-style :) I think it's better though, since it's type-aware.
Edit: I noticed Martin Broadhurst's comment on your question pointing out this is probably parsing a PE image. If so, look up the Jedi Code Library's PE image unit. I've never used it but I know it exists, and it's a translation of the C headers. It may include helper functions too. Using it might mean rewriting code rather than converting it, but you'll probably get cleaner, more Delphi-style code at the end.

Related

How can I call ioctl for interface list, or other ioctl stuff, on Free Pascal?

I've been Googling up and down, searching on the Free Pascal Wiki and even on some (obscure) mailing lists and have come completely empty on how to use ioctl() or fpioctl() on Free Pascal.
I have this bug report from Free Pascal's Bugtrack with code that enumerates the network interfaces.
The code does not compile since the libc unit has been deprecated.
A lot of similar questions about libc point to this wiki entry that talks about it's demise.
It does not give you any indication on where the SIOC*IF* stuff has gone.
Does that mean that most of ioctl functionality has gone?
Using find and grep, under /usr/share/fpcsrc/<fpc-version>/, I've been able to track some usage of fpioctl() in relation to terminals with the termios unit. Other stuff uses it but it looks like it's under other OSs.
Apart from that I'm unable to find anything of any use if you want to do something like:
if ioctl(sock, SIOCGIFCONF, #ifc)= 0 then begin
{...}
end;
So, can anyone from the Free Pascal Community give me a pointer to what's the current situation if one wants to do ioctl calls under Linux?
Does BaseUnix.FpIOCtl meet your use case? Have a look at the BaseUnix documentation. I found an example of using it here (reposted below).
program testrpi;
{$mode objfpc}{$H+}
uses
baseUnix,
classes,
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
sysutils;
const
I2C_SLAVE = 1795;
var
buf : packed array [0..1] of char;
c : char;
devPath : string = '/dev/i2c-1';
handle : Cint;
iDevAddr : Cint = $04;
begin
try
handle := fpopen(devPath,O_RDWR);
fpIOCtl(handle, I2C_SLAVE, pointer(iDevAddr));
except
writeln('Error initalizing i2c');
halt;
end;
while true do begin
write('Enter digit 1-9:');
readln(c);
if (not(c in ['1'..'9'])) then begin
writeln('oops - try again');
continue;
end;
buf[0] := chr(ord(c) - ord('0'));
try
fpwrite(handle, buf, 1);
except
writeln('Error writing');
halt;
end; //try
buf[0] := #99;
sleep(10);
try
fpread(handle, buf, 1);
except
writeln('Error reading');
halt;
end; //try
writeln('buf=', ord(buf[0]));
end; //while
fpclose(handle);
end.
The fpioctl bit has been answer by Mick and the FAQs. As for the constants, as the libc unit faq explains there is no clear cut solution, and thus for the more specialized constants there are no replacements.
OS specific constants should go in OS specific units (linux), and (somewhat) portable ones are usually grouped with the calls of the functionality they are for.
The old libc header was an rough header translation that was cleaned up somewhat, which was manageable for 32-bit Linux only, but unusable for a nix abstraction or even "just" multiplatform Linux. It was therefore abandoned.
In short it is best to either make a simple unit that abstracts the relevant parts or to just define the constants locally.

EntryPoint, Pointer and Disassembling by means of a TDisAsm instance

Using DisAsm32 by Russell Libby, disassembling a procedure/function/method is just a matter of passing a (consistent) Pointer to the procedure TDisAsm.Disassemble(Address: Pointer; Size: Cardinal = 0);.
So far, I have managed to disassemble any arbitrary procedure/method, even from a loaded external module (BPL/DLL) provided they are appropriately exported.
From the current process (The EXE image loaded by windows loader), I want to get a valid pointer to the entrypoint.
I want to come up with something akin to IDR (Interactive Delphi Compiler) provides through it's Code Viewer Tab but from the Exe running instance itself.
How can it be done? I'm not very comfortable with PE structures for the time being (but I am striving to, trust me) and wonder wether they are relevant for the purpose.
For PE structure reading/writing you can take a look at the open source JEDI library JCL, for example:
http://www.koders.com/delphi/fid38455E3CFDAF1F38C48DA3A295034E7015A4D01E.aspx?s=zip#L1810
The entrypoint of the running instance is "System.MainInstance"?
My own answer:
I came up with the working solution as follows
function TForm1.GetEntryPoint: Pointer;
var
DosHeader: PImageDosHeader;
NtHeaders : PImageNtHeaders;
OptionalHeader: PImageOptionalHeader;
begin
DosHeader := PImageDosHeader(HInstance + 0);
NtHeaders := PImageNtHeaders(HInstance + Cardinal(DosHeader^._lfanew));
OptionalHeader := PImageOptionalHeader(Cardinal(NtHeaders) + SizeOf(DWORD) + IMAGE_SIZEOF_FILE_HEADER);
//
Result := Pointer(HInstance + OptionalHeader^.AddressOfEntryPoint);
end;
Side Note:
SysInit.HInstance is the same as System.MainInstance: My preference goes for it as it sounds more C/C++ and find that more meaningfull for the case.
DisAsm32 goes beyond the call #Halt0 instruction when disassembling from the EntryPoint: It is designed to disassemble function/procedure/method and considers a ret instruction as the end.
The moral of it:
I will look for other more appealing disassembler such as BeaEngine and will keep the ball rolling.

How to use A-links and A-keywords with CHM help file in Delphi XE?

The "A" in A-links and A-keywords stands for "associative". This is because A-link keywords are actually not keywords at all. They are more like link or jump targets (known as anchors in H&M). They are never visible to the user like index keywords. They are known as "associative" because they are not absolute targets.
How to call CHM help by A-keyword in Delphi XE?
The Windows API function HTMLHelp is directly available in the Windows unit. You want the HH_ALINK_LOOKUP command.
If you're using the help system from HelpInfts, the HtmlHelpViewer unit contains THtmlHelpViewer, which contains various methods for dealing with ALinks - specifically LookupALink. Unfortunately, there seems to be no documentation of the type, so you'll have to drill down into the source yourself (it is quite simple, so you should not have too much trouble).
I don't see any support for it in helpintfs.
I tried myself once with D2006/FPC, and commited the results to FPC:
You'll need the unit "htmlhelp" from
http://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/packages/winunits-base/src/htmlhelp.pp?view=co
and do some ansi->unicode translation in that file (e.g. change all pchar to pansichar, replacint ptr(u)int with native(u)int etc)
This file has a constant HH_ALINK_LOOKUP that afaik can be used to lookup alinks and keywords.
This can be passed to the htmlhelp function. The below code is from Free Pascal and uses ansistrings, but it probably works analogous in Delphi
{$apptype console}
Uses HTMLHelp;
var
keyword : ansistring;
HelpfileName : AnsiString;
htmltopic : AnsiString;
res : Integer;
ah : PHH_AKLINK ;
Begin
Helpfilename:='rtl.chm';
keyword:='Sysutils' ;
New(ah);
fillchar(ah^,sizeof(ah^),#0);
ah.cbstruct:=sizeof(tagHH_AKLINK);
ah.fReserved := FALSE ;
ah.pszKeywords :=pansichar(keyword);
ah.pszUrl := NIL ;
ah.pszMsgText :='Text succes' ;
ah.pszMsgTitle :='Text fail';
ah.pszWindow := NIL ;
ah.fIndexOnFail:= false;
Res:=HtmlHelpA(0,pansichar(helpfilename) ,HH_DISPLAY_INDEX,PTRUINT(PAnsiChar(Keyword)));
// keyword search seems to have same effect.
Res:=HtmlHelpA(0,pansichar(helpfilename) ,HH_ALINK_LOOKUP,PTRUINT(AH));
writeln(ah.pszkeywords);
writeln(ah.pszurl);
writeln(ah.pszmsgtext);
writeln(ah.pszmsgtitle);
writeln(ah.pszwindow);
writeln(res);
readln;
end.

What is the "identity pointer" before a TTypeInfo there for?

If you poke around enough in Delphi internals, you'll find something strange and apparently undocumented about TTypeInfo records generated by the compiler. If the PTypeInfo points to a TTypeInfo record at address X, at X - 4 you'll find the next 4 bytes describe a pointer to X. For example:
procedure test(info: PTypeInfo);
var
addr: cardinal;
ptr: PPointer;
begin
addr := cardinal(info);
writeln('addr: ', addr);
dec(addr, 4);
ptr := PPointer(addr);
addr := cardinal(ptr^);
writeln('addr: ', addr);
end;
Pass any legitimate PTypeInfo generated by the compiler into this routine, and it'll output the same address twice. I've poked around in TypInfo.pas a little, but I don't see anything that mentions this "identity pointer" or what it's there for. Does anyone know why this is there? This appears to be true in every version of Delphi from at least D3 to D2010.
It's very simple: packages and dynamic linking.
BPLs are DLLs. DLLs are linked up through tables being patched, rather than all the code in the EXE or DLL linking against the DLL being patched (which would do great harm to sharing of read-only memory between multiple processes). To prevent the need for a reference to TypeInfo(SomeType) somewhere in the code, or typeinfo of an EXE or DLL, being modified when linking against the BPL, instead there's an indirection through the import table.
It's easy to see the difference when linking statically versus linking against a BPL in this program:
{$apptype console}
uses TypInfo, SysUtils;
type
TFoo = class(TObject);
var
x: PPTypeInfo;
begin
x := GetTypeData(TypeInfo(TFoo))^.ParentInfo;
Writeln(x^^.Name);
Writeln(Format('x %p', [x]));
Writeln(Format('x^ %p', [x^]));
end.
On my local machine, compiled with dcc32 test.pas, it outputs:
TObject
x 00401B64
x^ 00401B68
But when compiled with the RTL package with dcc32 -LUrtl test.pas, it outputs:
TObject
x 004051F0
x^ 40001DA4
Hopefully this clears it up.
Don't understand completely what is going on, but when you have a look at for example IsPublishedProp in the TypInfo unit, you'll see that it casts the ClassInfo of the instance as a pointer to a TypeInfo structure:
PTypeInfo(Instance.ClassInfo)
When you look at the ClassInfo method, it returns a simple pointer the value of which seems related to the vmt table:
Result := PPointer(Integer(Self) + vmtTypeInfo)^;
vmtTypeInfo has a value of -72. Four bytes before that at -76 is vmtInitTable. vmtTypeInfo is followed by FieldTable, MethodTable, DynamicTable etc.
the vmtInitTable value is used in for example TObject.CleanupInstance and passed to _FinalizeRecord as the pointer to the TypeInfo structure.
So the four bytes before the TypeInfo structure pointing to the TypeInfo structure seem to be there by design and part of the vmt structure.
Edit
As Mason rightly pointed out the above is a complete red herring (see comments). I am leaving the answer so others won't have to chase it down.
Update
To avoid confusion over variables and their addresses, I have rewritten Mason's test procedure as follows:
procedure test(info: PTypeInfo);
begin
writeln('value of info : ', cardinal(info));
writeln('info - 4 : ', cardinal(info) - 4);
writeln('value 4 bytes before: ', cardinal(PPointer(cardinal(info)-4)^));
end;
and call it with the following information:
procedure TryRTTIStuff;
begin
writeln('TPersistent');
test(TypeInfo(TPersistent));
writeln('TTypeKind enumeration');
test(TypeInfo(TTypeKind));
writeln('Integer');
test(TypeInfo(Integer));
writeln('Nonsense');
test(PTypeInfo($420000));
end;
The first three produce the results that Mason describes. I only added an extra writeln to show the pointer value for the last writeln. The last call in TryRTTIStuff is to show that when you do not pass in a pointer to a valid TypeInfo structure, you do not get the same value on the first and third writeln's for the call.
No clue yet as to what is going on with the TypeInfo. Maybe we should ask Barry Kelly as he is the author of the new D2010 RTTI so should know a lot about the old one as well...
maybe its a linked list that happens to be in contiguous memory:)

Elegant way for handling this string issue. (Unicode-PAnsiString issue)

Consider the following scenario:
type
PStructureForSomeCDLL = ^TStructureForSomeCDLL;
TStructureForSomeCDLL = record
pName: PAnsiChar;
end
function FillStructureForDLL: PStructureForSomeDLL;
begin
New(Result);
// Result.pName := PAnsiChar(SomeObject.SomeString); // Old D7 code working all right
Result.pName := Utf8ToAnsi(UTF8Encode(SomeObject.SomeString)); // New problematic unicode version
end;
...code to pass FillStructureForDLL to DLL...
The problem in unicode version is that the string conversion involved now returns a new string on stack and that's reclaimed at the end of the FillStructureForDLL call, leaving the DLL with corrupted data. In old D7 code, there were no intermediate conversion funcs and thus no problem.
My current solution is a converter function like below, which is IMO too much of an hack. Is there a more elegant way of achieving the same result?
var gKeepStrings: array of AnsiString;
{ Convert the given Unicode value S to ANSI and increase the ref. count
of it so that returned pointer stays valid }
function ConvertToPAnsiChar(const S: string): PAnsiChar;
var temp: AnsiString;
begin
SetLength(gKeepStrings, Length(gKeepStrings) + 1);
temp := Utf8ToAnsi(UTF8Encode(S));
gKeepStrings[High(gKeepStrings)] := temp; // keeps the resulting pointer valid
// by incresing the ref. count of temp.
Result := PAnsiChar(temp);
end;
One way might be to tackle the problem before it becomes a problem, by which I mean adapt the class of SomeObject to maintain an ANSI Encoded version of SomeString (ANSISomeString?) for you alongside the original SomeString, keeping the two in step in a "setter" for the SomeString property (using the same UTF8 > ANSI conversion you are already doing).
In non-Unicode versions of the compiler make ANSISomeString be simply a "copy" of SomeString string, which will of course not be a copy, merely an additional ref count on SomeString. In the Unicode version it references a separate ANSI encoding with the same "lifetime" as the original SomeString.
procedure TSomeObjectClass.SetSomeString(const aValue: String);
begin
fSomeString := aValue;
{$ifdef UNICODE}
fANSISomeString := Utf8ToAnsi(UTF8Encode(aValue));
{$else}
fANSISomeString := fSomeString;
{$endif}
end;
In your FillStructure... function, simply change your code to refer to the ANSISomeString property - this then is entirely independent of whether compiling for Unicode or not.
function FillStructureForDLL: PStructureForSomeDLL;
begin
New(Result);
result.pName := PANSIChar(SomeObject.ANSISomeString);
end;
There are at least three ways to do this.
You could change SomeObject's class
definition to use an AnsiString
instead of a string.
You could
use a conversion system to hold
references, like in your example.
You could initialize result.pname
with GetMem and copy the result of the
conversion to result.pname^ with
Move. Just remember to FreeMem it
when you're done.
Unfortunately, none of them is a perfect solution. So take a look at the options and decide which one works best for you.
Hopefully you already have code in your application to properly dispose off of all the dynamically allocated records that you New() in FillStructureForDLL(). I consider this code highly dubious, but let's assume this is reduced code to demonstrate the problem only. Anyway, the DLL you pass the record instance to does not care how big the chunk of memory is, it will only get a pointer to it anyway. So you are free to increase the size of the record to make place for the Pascal string that is now a temporary instance on the stack in the Unicode version:
type
PStructureForSomeCDLL = ^TStructureForSomeCDLL;
TStructureForSomeCDLL = record
pName: PAnsiChar;
// ... other parts of the record
pNameBuffer: string;
end;
And the function:
function FillStructureForDLL: PStructureForSomeDLL;
begin
New(Result);
// there may be a bug here, can't test on the Mac... idea should be clear
Result.pNameBuffer := Utf8ToAnsi(UTF8Encode(SomeObject.SomeString));
Result.pName := Result.pNameBuffer;
end;
BTW: You wouldn't even have that problem if the record passed to the DLL was a stack variable in the procedure or function that calls the DLL function. In that case the temporary string buffers will only be necessary in the Unicode version if more than one PAnsiChar has to be passed (the conversion calls would otherwise reuse the temporary string). Consider changing the code accordingly.
Edit:
You write in a comment:
This would be best solution if modifying the DLL structures were an option.
Are you sure you can't use this solution? The point is that from the POV of the DLL the structure isn't modified at all. Maybe I didn't make myself clear, but the DLL will not care whether a structure passed to it is exactly what it is declared to be. It will be passed a pointer to the structure, and this pointer needs to point to a block of memory that is at least as large as the structure, and needs to have the same memory layout. However, it can be a block of memory that is larger than the original structure, and contain additional data.
This is actually used in quite a lot of places in the Windows API. Did you ever wonder why there are structures in the Windows API that contain as the first thing an ordinal value giving the size of the structure? It's the key to API evolution while preserving backwards compatibility. Whenever new information is needed for the API function to work it is simply appended to the existing structure, and a new version of the structure is declared. Note that the memory layout of older versions of the structure is preserved. Old clients of the DLL can still call the new function, which will use the size member of the structure to determine which API version is called.
In your case no different versions of the structure exist as far as the DLL is concerned. However, you are free to declare it larger for your application than it really is, provided the memory layout of the real structure is preserved, and additional data is only appended. The only case where this wouldn't work is when the last part of the structure were a record with varying size, kind of like the Windows BITMAP structure - a fixed header and dynamic data. However, your record looks like it has a fixed length.
Wouldn't PChar(AnsiString(SomeObject.SomeString)) work?

Resources