Recent

Author Topic: Inline asm problem with assign  (Read 18377 times)

Rekumkacz

  • New Member
  • *
  • Posts: 21
Re: Inline asm problem with assign
« Reply #15 on: June 23, 2015, 02:22:21 pm »
In Delphi7

Code: [Select]
mov        eax,var_1 
mov        edx,var_2
call       @LStrAsg
       
     
Throughout my life I have written and debuging in Delphi, it was time to shift from thinking about compiling Delphi code.                   

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12599
  • FPC developer.
Re: Inline asm problem with assign
« Reply #16 on: June 23, 2015, 02:49:06 pm »
Why is for one "mov" used and the other "lea" ??
(* yeah, my asm is very rusty)

I'd expect incr_ref and decr_ref to use VAR (by reference) parameter semantics, since they
must be able to NIL the variable if refcount reaches zero.

So you must pass the address to the variable, not its contents.

rvk

  • Hero Member
  • *****
  • Posts: 6925
Re: Inline asm problem with assign
« Reply #17 on: June 23, 2015, 02:54:11 pm »
Why is for one "mov" used and the other "lea" ??
(* yeah, my asm is very rusty)

I'd expect incr_ref and decr_ref to use VAR (by reference) parameter semantics, since they
must be able to NIL the variable if refcount reaches zero.

So you must pass the address to the variable, not its contents.
That still doesn't explain why for the fpc_ansistr_incr_ref a "mov" is used and for the fpc_ansistr_decr_ref a "lea" in assembler of "var_1 := var_2;"

Code: [Select]
  asm
    mov    eax, [var_2]
    call   my_fpc_ansistr_incr_ref
    lea    eax, [var_1]
    call   my_fpc_ansistr_decr_ref
    mov    eax, [var_2]
    mov    [var_1], eax
  end;


Pure compiler asm:
Code: [Select]
unit1.pas:68                      var_1 := var_2;
00428042 8b45f0                   mov    -0x10(%ebp),%eax
00428045 e826f2fdff               call   0x407270 <fpc_ansistr_incr_ref>
0042804A 8d45f4                   lea    -0xc(%ebp),%eax
0042804D e89ebbfdff               call   0x403bf0 <fpc_ansistr_decr_ref>
00428052 8b45f0                   mov    -0x10(%ebp),%eax
00428055 8945f4                   mov    %eax,-0xc(%ebp)


Code: [Select]
call       @LStrAsg
And have you looked in the source of Delphi what LStrAsg exactly does :)

It also increases and decreases reference count of memory locations.


I'm not sure what you are trying to do exactly with the assembler because the compiler is really efficient.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12599
  • FPC developer.
Re: Inline asm problem with assign
« Reply #18 on: June 23, 2015, 03:02:46 pm »
I'd expect incr_ref and decr_ref to use VAR (by reference) parameter semantics, since they
must be able to NIL the variable if refcount reaches zero.

So you must pass the address to the variable, not its contents.

That still doesn't explain why for the fpc_ansistr_incr_ref a "mov" is used and for the fpc_ansistr_decr_ref a "lea" in assembler of "var_1 := var_2;"

That means that incr_ref is still by value, which is ok, since increasing generally doesn't lead to 0 :)


rvk

  • Hero Member
  • *****
  • Posts: 6925
Re: Inline asm problem with assign
« Reply #19 on: June 23, 2015, 03:16:15 pm »
That means that incr_ref is still by value, which is ok, since increasing generally doesn't lead to 0 :)

Argh... I see now:
Code: [Select]
Procedure fpc_ansistr_incr_ref (S : Pointer); compilerproc;
Procedure fpc_ansistr_decr_ref (Var S : Pointer); compilerproc;
So the fpc_ansistr_decr_ref expects it as a Var pointer.

Hence the difference in calling it.

mov    eax, [var]
call   fpc_ansistr_incr_ref

lea    eax, [var]
call   fpc_ansistr_decr_ref


Yeah, you really need to know what you're doing in assembler :)
« Last Edit: June 23, 2015, 03:18:13 pm by rvk »

Rekumkacz

  • New Member
  • *
  • Posts: 21
Re: Inline asm problem with assign
« Reply #20 on: June 24, 2015, 08:48:17 am »
Hero Member i don't have a Delphi.

fpc_ansistr_decr_ref and fpc_ansistr_incr_ref
These functions are used by the compiler not for user?
Is there a ready function that combines these functions into one like LStrAsg?

rvk

  • Hero Member
  • *****
  • Posts: 6925
Re: Inline asm problem with assign
« Reply #21 on: June 24, 2015, 09:34:17 am »
Something like this:
Code: [Select]
Procedure fpc_AnsiStr_Assign (Var DestS : Pointer;S2 : Pointer);[Public,Alias:'FPC_ANSISTR_ASSIGN'];  compilerproc;
{
  Assigns S2 to S1 (S1:=S2), taking in account reference counts.
}

But could you first explain why you want to do this in assembler? Using S1 := S2; is as much optimized as you can get. Do you want to optimize? Then don't use a call but do it like we showed you before. Is it just for "fun" and learning about assembler? Then don't use a ready made function :)

The fpc_AnsiStr_Assign compiler function is not assembler itself. So I'm not sure what's to gain there.

fpc_ansistr_decr_ref and fpc_ansistr_incr_ref
These functions are used by the compiler not for user?
Well... if you are going to mess around with assembler these functions are also for the user. In assembler you need to do a lot more yourself like this reference counting.
« Last Edit: June 24, 2015, 09:37:05 am by rvk »

Rekumkacz

  • New Member
  • *
  • Posts: 21
Re: Inline asm problem with assign
« Reply #22 on: June 24, 2015, 10:23:47 am »
I take part in competitions CTF 's .
Often the programs are written in Delphi and Lazarus .
For example, there are all functions of checking the correctness of the entered password .
 I wanted to learn about specific function calls.
Such as the function TControl.SetText for typing in Edit1 , edx and eax are required to do.

rvk

  • Hero Member
  • *****
  • Posts: 6925
Re: Inline asm problem with assign
« Reply #23 on: June 24, 2015, 11:01:03 am »
I take part in competitions CTF 's .
Often the programs are written in Delphi and Lazarus .
For example, there are all functions of checking the correctness of the entered password .
I'm still not sure, from this description, why you want to do this in assembler. There are other ways, which are portable between Delphi and Lazarus (in Pascal), to achieve these goals.

Quote
Such as the function TControl.SetText for typing in Edit1 , edx and eax are required to do.
edx and eax are required? You mean it is required that you use assembler for this? It's a requirement in the competition? In that case you will always have differences in Delphi and Lazarus. Assembler is at such a low level that you can't just write just one code as you saw with fpc_AnsiStr_Assign for FPC and LStrAsg for Delphi which are effectively the same but are implemented differently. But both function have some overhead. That's why in pure compiler code it's done like I showed you (just calling fpc_ansistr_xxxx_ref twice and reassign the pointer).

But if you want to learn about the inners of FPC/Lazarus and want to code in assembler (or read already made assembler-code) you do need to know about the fpc_ansistr_decr_ref, fpc_ansistr_incr_ref and other functions.

And like the header states (see the Public,Alias part) these functions are made available to the user when doing things in pure assembler for just that reason:
Code: [Select]
Procedure fpc_ansistr_decr_ref (Var S : Pointer); [Public,Alias:'FPC_ANSISTR_DECR_REF'];  compilerproc;
{
  Decreases the ReferenceCount of a non constant ansistring;
  If the reference count is zero, deallocate the string;
}

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12599
  • FPC developer.
Re: Inline asm problem with assign
« Reply #24 on: June 24, 2015, 11:06:11 am »
(note that on this level everything is formally undocumented in both delphi and fpc)

Rekumkacz

  • New Member
  • *
  • Posts: 21
Re: Inline asm problem with assign
« Reply #25 on: June 24, 2015, 11:12:49 am »
Gets such a program written in Delphi or Lazarus .
I open in a debugger and I have a function that calculates the password.
Copies pure asm code to Lazarus and repairing the link to the call 's and profit.

Similarly, it gets when writing Keygens.

Thaddy

  • Hero Member
  • *****
  • Posts: 18711
  • To Europe: simply sell USA bonds: dollar collapses
Re: Inline asm problem with assign
« Reply #26 on: June 24, 2015, 11:52:56 am »
@ Rekumkacz: If I understand you correctly you expect Delphi and FPC to be compatible on a (near) binary level: well, they are not! Nor will that ever be the case.
If it's a hacking competition you should be able to figure out the compiler internals for both Delphi and Freepascal. As Marco implies: the compilers are compatible to a very large extend on the pascal language level, but they are totally different in the generated assembly code.

You sometimes can use and copy asm code between the two, but if there are calls to compiler magic/ internal routines this will  always fail.
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

Rekumkacz

  • New Member
  • *
  • Posts: 21
Re: Inline asm problem with assign
« Reply #27 on: June 24, 2015, 12:30:15 pm »
The code that use as normal functions such as IntToStr, operations on variables like adding compile very well without problems.
As it appears strange call as I wrote in the first post , running becomes impossible.

rvk

  • Hero Member
  • *****
  • Posts: 6925
Re: Inline asm problem with assign
« Reply #28 on: June 24, 2015, 12:50:11 pm »
The code that use as normal functions such as IntToStr, operations on variables like adding compile very well without problems.
As it appears strange call as I wrote in the first post , running becomes impossible.
LStrLAsg is also a "strange" call. You can't use that one either without declaring it as an external function in Delphi. It's the same in FPC. Those fpc_AnsiStr_xxxx_Ref functions need to be declared before you can use them in your code.

But okay... I already showed you how it's done in pure compiler-code:
Code: [Select]
procedure my_fpc_AnsiStr_Decr_Ref (Var S : Pointer);external name 'FPC_ANSISTR_DECR_REF';
procedure my_fpc_AnsiStr_Incr_Ref (Var S : Pointer);external name 'FPC_ANSISTR_INCR_REF';

procedure TForm1.Button1Click(Sender: TObject);
var
  var_1, var_2: String;
begin
  var_1 := 'Text1';
  var_2 := 'Text2';

  // effectively: var_1 := var_2;
  {$ASMMODE intel}
  asm
    mov    eax, [var_2]
    call   my_fpc_ansistr_incr_ref
    lea    eax, [var_1]
    call   my_fpc_ansistr_decr_ref
    mov    eax, [var_2]
    mov    [var_1], eax
  end;

  edit1.Text := var_1;
  edit2.Text := var_2;
end;

If you really want the call with fpc_ansistr_assign (like you say Delphi does with LStrLAsg) you could do this:
(it does the fpc_ansistr_xxxx_ref internally, in fpc_ansistr_assign, for you)

Code: [Select]
Procedure fpc_AnsiStr_Assign (Var DestS : Pointer;S2 : Pointer);external name 'FPC_ANSISTR_ASSIGN';

procedure TForm1.Button1Click(Sender: TObject);
var
  var_1, var_2: String;
  p1,p2: pointer;
begin
  var_1 := 'Text1';
  var_2 := 'Text2';

  {$ASMMODE intel}
  asm
    mov    edx, [var_2]
    lea    eax, [var_1]
    call   fpc_ansistr_assign
  end;

  edit1.Text := var_1;
  edit2.Text := var_2;
end;

(Though this last method is less efficient)

Does that answer your question? :)

Or are you trying to "hack" the binary code?
In that case you would need to know the memory location of the fpc_ansistr_assign function.
If so... with what program are you doing this and how would you do this with Delphi code?
« Last Edit: June 24, 2015, 12:54:16 pm by rvk »

Rekumkacz

  • New Member
  • *
  • Posts: 21
Re: Inline asm problem with assign
« Reply #29 on: June 24, 2015, 01:15:03 pm »
YES  :D
I don't have a Delphi and i don't have any information about recognizes the LStrLAsg function or similar without importing from dll or another library.

So off topic , what records contain what?
ebp - local varibles
ebx - information about visual component (Edit, Label, etc)
esi - ?

 

TinyPortal © 2005-2018