Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2021-09

trying to read an EXE

9 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

duilio foschi

today I did an experiment that gave me surprising results (due to my ignorance,
of course).

I have an application written in Lazarus and I need to do one fix only.

This line

   result:=EncodeDate(
   cmbYear.ItemIndex+2005,
   cmbMonth.ItemIndex+1,
   1);

needs to be changed into

   result:=EncodeDate(
   cmbYear.ItemIndex+2006,
   cmbMonth.ItemIndex+1,
   1);

I thought it would be easy to use an hex editor like PSPad hex, find the number
2005 as 07D5 then fix it (maybe after the right guess in case of multiple hits).

To my surprise, I could not find the word 07D5. As I vaguely remember the big endian/little endian question, I tried to look for D507: no hit.

In order to dig into the question, I created a Lazarus windows application made of a TCombobox and a TButton. I used v. 2.0.6 on windows 7.

I added the following code:

procedure TForm1.Button1Click(Sender: TObject);
var
   a:string;
   i:integer;
begin
   cmbYear.Items.Add('2020');
   cmbYear.Items.Add('2021');
   Caption:='peppe';
   i:=cmbYear.ItemIndex+2005;
   Caption:=inttostr(i);
end;

I compiled/linked that application then opened the EXE using PsPad Hex.

Looking for string 'peppe', I can easily spot the part that contains the code of interest.

Please see here for a screenshot of PsPad Hex:
https://i.ibb.co/2M054Qx/1.jpg

(I encircled a few familiar names).

I cannot understand how this instruction

   i:=cmbYear.ItemIndex+2005;

is coded here.

I am no assembly expert, but I expect that the compiler would translate the instruction into something like

move 2005 to register X
add register X to register Y (where register Y represents cmbYear.ItemIndex)
move register Y to register Z (where register Z represents var i)

In any case I would expect that the figure 2005 (07D5) be written somewhere, but facts prove me wrong.

I am very curious: what really happens in the EXE?

In which form gets this instruction compiled?
   i:=cmbYear.ItemIndex+2005;

Could someone explain?

Thank you

Peppe
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20210903/5b89a1ac/attachment.html>

Reply by email

Bart
to duilio foschi
PM duilio foschi wrote
In which form gets this instruction compiled? i:=cmbYear.ItemIndex+2005;

Compile wit -al and then open the resulting .s file in a texteditor. You'll see the assembler that the compiler generates for that line:

It will be preceeded by a comment more or less like this:
# i:=cmbYear.ItemIndex+2005;
Bart

Reply by email

Sven Barth
to duilio foschi: today I did an experiment that gave me surprising results (due to my of course). I have…

duilio foschi via lazarus schrieb am Fr.,
3. Sep. 2021, 23:08:

Looking for string 'peppe', I can easily spot the part that contains the code of interest.

In addition to what Bart wrote: the string will be located in a different section (usually .rdata) than where it will be used (in this case .text) which will only be a reference.

Regards,
Sven
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20210904/d418c95c/attachment.html>

Reply by email

Christo Crause
to duilio foschi: today I did an experiment that gave me surprising results (due to my of course). I have…

On Fri, Sep 3, 2021 at 11:08 PM duilio foschi via lazarus <

Show quoted text 7 lines
wrote: I thought it would be easy to use an hex editor like PSPad hex, find the number 2005 as 07D5 then fix it (maybe after the right guess in case of multiple hits).

As a test I compiled a simple example on x86_64 with integers for the year, month and day, placed a break point on the encodedate call and inspected the assembler:
/home/christo/tmp/project1.lpr:14 date := EncodeDate(y+$1a2b3c4d, m, d);
OpCode Assembler
8B05CEF70700 mov eax,[rip+$0007F7CE]
678DB84D3C2B1A lea edi,[eax+$1A2B3C4D]
81E7FFFF0000 and edi,$0000FFFF
In this case the constant $1a2b3c4d is added to the content of register eax, encoded in the lea instruction. The constant is recognizable as a little endian byte sequence 4D 3C 2B 1A following the lea instruction bytes 67 8D B8. Since your setup is probably different, your code may be compiled into slightly different instruction sequences so you have to inspect the generated instruction sequence, as mentioned by Bart.

Also note that testing with a string value will likely yield completely different results, since a string literal will in most cases be stored separately as mentioned by Sven. This is in contrast to your original question of modifying an integerconstant which can easily be encoded as part of an instruction.

To my surprise, I could not find the word 07D5. As I vaguely remember the

big endian/little endian question, I tried to look for D507: no hit.

This is somewhat surprising since my simple example shows the little endian encoded constant as part of the instruction bytes. However, you have to look at the specific instructions generated in your program.

I assume this is for remote patching of a large executable, else it would be simpler to just distribute the recompiled version? -------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20210904/f417fbea/attachment.html>

Reply by email

duilio foschi
to duilio foschi: today I did an experiment that gave me surprising results (due to my of course). I have…

I followed Bart's suggestion and added the -al switch to the fpc.cfg file.

This was probably the right move, as - after a new compile - I could see the wanted .s file beside the regular EXE.

I uploaded the .s file here:
https://mega.nz/file/rlpyHa7b#fx0LYTjapmUdFRkzVGCCzFFogqYuEu7UvYQ5HtilLks

I opened the new .s file with a text editor and had a new surprising result: the instruction

i:=cmbYear.ItemIndex+2005;

is nowhere to be found.

I tried to find the figure 2005 both as 07D5 and as D507: no hit.

I tried to find the string 'peppe' (that I correctly find in the EXE) in the S file: no hit.

I tried to find the string 'peppe' in hex format (7065707065) in the S file: no hit.

I tried to understand where the OnClick event could be written, but - with little surprise - I could not.

I recompiled with no debug info + using the option 'no optimization'. The new .s file is stored here
https://mega.nz/file/X1B2mJpL#smqDJOoDOBZOMoDUpeNutXw3C3YgqHurbdC6L7m2vf4

The new .s file gives no new information than the old one.

With all this: the EXE works ok.

This case shows that I have a lot of things to learn.

Any help?

Peppe

PS:

if interested:

unit1.lfm
https://mega.nz/file/O1IDhIwb#0SDAninq5yfTOKELksfTRnaXqpIocwh3ugthDzFK2G8

unit1.pas
https://mega.nz/file/fgYjFQzJ#wuaS4A7CeTR0Ra35_E5gk8ggGlAFPBqaSJS_p_yi8Ss

PM duilio foschi wrote 88 lines
today I did an experiment that gave me surprising results (due to my ignorance, of course). I have an application written in Lazarus and I need to do one fix only. This line result:=EncodeDate( cmbYear.ItemIndex+2005, cmbMonth.ItemIndex+1, 1); needs to be changed into result:=EncodeDate( cmbYear.ItemIndex+2006, cmbMonth.ItemIndex+1, 1); I thought it would be easy to use an hex editor like PSPad hex, find the number 2005 as 07D5 then fix it (maybe after the right guess in case of multiple hits). To my surprise, I could not find the word 07D5. As I vaguely remember the big endian/little endian question, I tried to look for D507: no hit. In order to dig into the question, I created a Lazarus windows application made of a TCombobox and a TButton. I used v. 2.0.6 on windows 7. I added the following code: procedure TForm1.Button1Click(Sender: TObject); var a:string; i:integer; begin cmbYear.Items.Add('2020'); cmbYear.Items.Add('2021'); Caption:='peppe'; i:=cmbYear.ItemIndex+2005; Caption:=inttostr(i); end; I compiled/linked that application then opened the EXE using PsPad Hex. Looking for string 'peppe', I can easily spot the part that contains the code of interest. Please see here for a screenshot of PsPad Hex: https://i.ibb.co/2M054Qx/1.jpg (I encircled a few familiar names). I cannot understand how this instruction i:=cmbYear.ItemIndex+2005; is coded here. I am no assembly expert, but I expect that the compiler would translate the instruction into something like move 2005 to register X add register X to register Y (where register Y represents cmbYear.ItemIndex) move register Y to register Z (where register Z represents var i) In any case I would expect that the figure 2005 (07D5) be written somewhere, but facts prove me wrong. I am very curious: what really happens in the EXE? In which form gets this instruction compiled? i:=cmbYear.ItemIndex+2005; Could someone explain? Thank you Peppe

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20210904/7dc2b4f6/attachment-0001.html>

Reply by email

Christo Crause
to duilio foschi

On Sat, Sep 4, 2021 at 11:53 AM duilio foschi via lazarus <

Show quoted text 17 lines
wrote: I followed Bart's suggestion and added the -al switch to the fpc.cfg file. This was probably the right move, as - after a new compile - I could see the wanted .s file beside the regular EXE. I uploaded the .s file here: https://mega.nz/file/rlpyHa7b#fx0LYTjapmUdFRkzVGCCzFFogqYuEu7UvYQ5HtilLks I opened the new .s file with a text editor and had a new surprising result: the instruction i:=cmbYear.ItemIndex+2005; is nowhere to be found.

The assembler file you posted is for the .lpr file only. The -al option generates the assembler files per compilation unit, before the project gets linked. Also it doesn't show the machine code (this resides in the compiled object file), which seems to be what you want to inspect/modify.

The easiest way to see both the machine code, the disassembled code and the Pascal code from inside Lazarus is to place a breakpoint on the line of interest, run until you hit that breakpoint, then switch to the Assembler view.

An alternative is to use a tool such as objdump or dumpbin to disassemble the executable file. There are options to include source code lines in the output if available as debug information.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20210904/9f514f2f/attachment.html>

Reply by email

duilio foschi
to duilio foschi: today I did an experiment that gave me surprising results (due to my of course). I have…
x Christo ;

for the problem in question, I was running short of time, so I went back to the source, fixed the line and recompiled.

However this question picked my curiosity and I'd like to know more

The easiest way to see both the machine code, the disassembled code and

the Pascal code from inside Lazarus is to place a breakpoint on the line of interest, run until you hit that breakpoint, then switch to the Assembler view.

I did that and it is very interesting

An alternative is to use a tool such as objdump or dumpbin to disassemble

the executable file.

objdump seems to be a unix tool. AFAIK dumpbin will only work from Visual Studio.

Is there a way to see the assembly on a 2nd monitor while an EXE is run? Without having the EXE source code, I mean

Thank you

Peppe
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20210905/013e7cc6/attachment.html>

Reply by email

Christo Crause
to duilio foschi

On Sun, Sep 5, 2021 at 12:50 PM duilio foschi via lazarus <

Show quoted text 8 lines
wrote: > An alternative is to use a tool such as objdump or dumpbin to disassemble the executable file. objdump seems to be a unix tool. AFAIK dumpbin will only work from Visual Studio.

You can get GNU binutils for Windows here:
https://sourceforge.net/projects/mingw/files/MinGW/Base/binutils/binutils-2.28/

Is there a way to see the assembly on a 2nd monitor while an EXE is run? Without having the EXE source code, I mean

This sounds as if you want to debug the executable? This is doable, but without source code you will have to step through the assembler instructions manually, or know where in the code to put breakpoints. Use your favourite Windows debugger, if you don't have one try gdb (part of the full large Lazarus install I believe). Even if this is what you want to do, I suggest you dump the disassembled code into a text file, open this and study it. If the executable is stripped it may be very difficult to make sense of the assembler code.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20210905/ed6a1c72/attachment.html>

Reply by email

duilio foschi
to Christo Crause

a new world to discover.

Thanks a lot

Peppe

PM Christo Crause wrote 28 lines
On Sun, Sep 5, 2021 at 12:50 PM duilio foschi via lazarus < > wrote: > > An alternative is to use a tool such as objdump or dumpbin to > disassemble the executable file. > > objdump seems to be a unix tool. AFAIK dumpbin will only work from Visual > Studio. > You can get GNU binutils for Windows here: https://sourceforge.net/projects/mingw/files/MinGW/Base/binutils/binutils-2.28/ > Is there a way to see the assembly on a 2nd monitor while an EXE is run? > Without having the EXE source code, I mean > This sounds as if you want to debug the executable? This is doable, but without source code you will have to step through the assembler instructions manually, or know where in the code to put breakpoints. Use your favourite Windows debugger, if you don't have one try gdb (part of the full large Lazarus install I believe). Even if this is what you want to do, I suggest you dump the disassembled code into a text file, open this and study it. If the executable is stripped it may be very difficult to make sense of the assembler code.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20210905/bf782ea8/attachment.html>

Reply by email