Dynamic vs. Static DLL Linking is different - windows

I have a C DLL and want to call it from Delphi XE3 Update 2.
Curiously it seems that in my project calling it dynamically IS different to calling it statically. Here is the 'minimal' code to reproduce (I have changed the Lib/functionnames):
program testProject;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, System.classes, Windows;
function keylist_open (keylist: PPointer): Integer; external 'libLib';
var
Handle: HINST;
DLLName: PChar = 'libLib.dll';
type
Tkeylist_open = function(keylist: PPointer): Integer; stdcall;
const
keylist_openDynamic: Tkeylist_open = nil;
var
keylist: Pointer;
begin
Handle := LoadLibrary(DLLName);
if Handle = 0 then
Exit;
#keylist_openDynamic := GetProcAddress(Handle, 'keylist_open');
keylist_open(#keylist);
if (keylist = nil) then
Writeln('static: keylist is nil');
keylist_openDynamic(#keylist);
if (keylist = nil) then
Writeln('dynamic: keylist is nil');
end.
The output is
static: keylist is nil
Which means that calling the function dynamically is different from statically.
the keylist indeed gets initialized correctly by calling it dynamically.
looking into the generated assembler code i realize that the variable 'keylist'
is put into the eax register:
testProject.dpr.34: keylist_open(#keylist);
004D16A2 B804B04D00 mov eax,$004db004
004D16A7 E8ECC6FFFF call keylist_open
then
testProject.dpr.12: function keylist_open (keylist: PPointer): Integer; external 'libLib';
004CDD98 FF255CC54D00 jmp dword ptr [$004dc55c]
and another jump
libLib.keylist_open:
5B364508 E903A23D00 jmp $5b73e710
but then the dll (i do not know which function this is, some entry point or the keylist routine) there is
5B73E710 55 push ebp
5B73E711 8BEC mov ebp,esp
5B73E713 81ECDC000000 sub esp,$000000dc
5B73E719 53 push ebx
5B73E71A 56 push esi
5B73E71B 57 push edi
5B73E71C 8DBD24FFFFFF lea edi,[ebp-$000000dc]
5B73E722 B937000000 mov ecx,$00000037
5B73E727 B8CCCCCCCC mov eax,$cccccccc
...
it seems that the eax parameter is being overwritten in eax.
two lines later the code for the dynamic call is:
testProject.dpr.37: keylist_openDynamic(#keylist);
004D16CE 6804B04D00 push $004db004
004D16D3 FF15F0564D00 call dword ptr [$004d56f0]
jumping to
libLib.keylist_open:
5B364508 E903A23D00 jmp $5b73e710
and thus to the very same code. But as the parameter is now not stored in eax, overwriting eax does not matter.
call anyone shed a light here, what is going wrong, i.e. what is wrong with my static code and why?

The two versions differ in the calling convention. The run time linking variant uses stdcall and the load time linking variant uses register.
Make the calling conventions match and all will be well.

Related

How to pass a struct by value in x86 assembly

I'm trying to call a function from the windows api in masm.
This is the signature:
BOOL WINAPI SetConsoleScreenBufferSize(
_In_ HANDLE hConsoleOutput,
_In_ COORD dwSize
);
The COORD structure dwSize is passed by value, but when I try to call it the function fails.
Looks like this:
.DATA
dwSize COORD <20, 20>
.CODE
INVOKE SetConsoleScreenBufferSize,
hConsoleOutput,
dwSize
This causes a type error and the program won't assemble. If I pass a reference to the struct, the program assembles but the function does not work. I've tried with other functions that accept structs by value, with no success.
Hans is correct Invoke doesn't understand how to pass a struct by value. COORD is 2 16-bit values which happens to be the size of a DWORD. In the case of COORD you can cast it to a DWORD as a parameter to Invoke . This should work:
.DATA
dwSize COORD <20, 20>
.CODE
INVOKE SetConsoleScreenBufferSize,
hConsoleOutput,
DWORD PTR [dwSize]
Note: It is important to understand that since COORD happened to be the size of a DWORD we could get away with this. For structures that don't have a size that can be pushed on the stack directly you'd have to build the structure on the stack and use the CALL instruction rather than Invoke.
COORD is just two 16-bit numbers packed together and passed as normal 32-bit number.
MSVC (x86) turns
COORD cord = { 0x666, 0x42 };
SetConsoleScreenBufferSize(0, cord);
into
33db xor ebx,ebx
66c745986606 mov word ptr [ebp-68h],666h ; store cord.x
66c7459a4200 mov word ptr [ebp-66h],42h ; store cord.y
ff7598 push dword ptr [ebp-68h] ; push the whole struct
53 push ebx ; push 0
ff1540104000 call dword ptr [image00400000+0x1040 (00401040)] ; SetConsoleScreenBufferSize
After push'ing but before the call the stack starts with:
00000000 00420666 ...
xor-zeroing a register and then pushing that is a missed optimization vs. push 0 of an immediate zero. Storing to the stack first is also only because the source was compiled with optimization disabled.

Cannot access stack elements from another method - Assembly [duplicate]

My questions pertain to the actions that seem to happen between the line when context is changed especially concerning RSP and RBP.
Given this very simple program:
Reading symbols from ./function_call...done.
(gdb) disass main
Dump of assembler code for function main:
0x00000000004004d6 <+0>: push rbp
0x00000000004004d7 <+1>: mov rbp,rsp
0x00000000004004da <+4>: mov esi,0x2
0x00000000004004df <+9>: mov edi,0x1
0x00000000004004e4 <+14>: call 0x4004b6 <add_and_7>
0x00000000004004e9 <+19>: mov eax,0x0
0x00000000004004ee <+24>: pop rbp
0x00000000004004ef <+25>: ret
End of assembler dump.
(gdb) disass add_and_7
Dump of assembler code for function add_and_7:
0x00000000004004b6 <+0>: push rbp
0x00000000004004b7 <+1>: mov rbp,rsp
0x00000000004004ba <+4>: mov DWORD PTR [rbp-0x14],edi
0x00000000004004bd <+7>: mov DWORD PTR [rbp-0x18],esi
0x00000000004004c0 <+10>: mov DWORD PTR [rbp-0x4],0x7
0x00000000004004c7 <+17>: mov edx,DWORD PTR [rbp-0x14]
0x00000000004004ca <+20>: mov eax,DWORD PTR [rbp-0x18]
0x00000000004004cd <+23>: add edx,eax
0x00000000004004cf <+25>: mov eax,DWORD PTR [rbp-0x4]
0x00000000004004d2 <+28>: add eax,edx
0x00000000004004d4 <+30>: pop rbp
0x00000000004004d5 <+31>: ret
End of assembler dump.
(gdb) list
1 int add_and_7( int num1, int num2 ) {
2 int seven = 7;
3 return num1 + num2 + seven;
4 }
5
6 int main() {
7 add_and_7( 1, 2 );
8 return 0;
9 }
All functions start off with push rbp which I as I understand it is preserving the parent context onto the stack. How does the parent function know how to rebuild itself? Are the necessary steps built into call and ret?
Then the rsp is always moved to rbp. As I have read this sets the new stack base to be in the context of the current function. What I can't seem to figure out is when or how stack pointer was set to that point in the first place. My best guess is the assembly function call does this, is that whats happening?
Lastly when a method returns it seems like eax is the register that is used for the parent function to utilize the return of its child function. Is eax explicitly used for this or is this just a convention with my compiler and architecture?
How does the parent function know how to rebuild itself ? Are the necessary steps built into call and ret?
Before calling a function, current status of registers are saved, as well as the return address. call instruction jumps to particular address, where the called function begins. The return address is pushed onto stack. When called function returns, ret instruction pops previously pushed return address and goes to that location.
Then the rsp is always moved to rbp
rbp is previously pushed onto stack to be able to restore rbp's value from caller's function. Then, rsp is moved to rbp to create a new stack frame for callee function. The new base pointer has been set up. So currently, rbp and rsp points to the same addresses. If there are other push instructions, esp is automatically adjusted. When function is done, the pop ebp instruction restores previously pushed stack base pointer address.
Push and Pop modify the stack pointer - SP.
Call pushes FLAGS - status register as well as the RA - return address.
Ret pops the FLAGS pops and jumps to the return address.
As rkhb said, the need to keep certain registers as they are comes from the calling conventions.

How to properly use PUSH and POP

I have a code that has 3 procedures, one to get an input from the user, one to display a multiplication result, and lastly one for an error message. I am trying to implement the PUSH and POP operations and get my code in to the stack. It will seem long but it makes sense to me, here it is...
.data
line BYTE "The answer is ",0
line2 BYTE "Enter a number",0
kline3 BYTE Wrong.",0
int SWORD ?
.code
Val PROC
call ReadInt
mov int,edx
cmp int, 10000
jl 1
jmp end
L1: cmp intVal1, -10000
jg 2
call error
jmp end
2: ret
Val ENDP
main PROC
call Val
call Val
imul val, val
exit
main ENDP
END main
All this simply does it call to get 2 inputs twice and then call to display the the multiplied result. My question is how do you implement push and pop in to here to have it all make sense?
I would assume that you need to push in the GetValue procedure to put in input in to the stack and then pop it after each call in the main procedure and maybe do the same with the display procedure?
I am just struggling to figure it out so any help would be great!
PS. This code is an asm file in visual studio 2010
Your first call to GetValue stores its result in intVal. But then your second call to GetValue also stores its result in intVal, so the first result is forever lost.
Your MultiplyAndDisplay function expects one of the operands in intVal, and the other operand in eax. So, what you need to do is push [intVal] after the first call to GetValue, and pop eax after the second call to GetValue.
Note that the square brackets in push [intVal] are in some notation that actually makes sense, but if I remember correctly the microsoft assembler does not support that notation which actually makes sense, so you might have to code push intVal instead, or push dword ptr intVal, or something nonsensical like that to get it to work.
Because your question is tagged MASM, this is a MASM answer:
Your code can be restructured in a way that uses the MASM directive PROC with parameters and the INVOKE directive for parameter passing:
MultiplyAndDisplay PROC val1: SDWORD, val2: SDWORD
mov eax, val1
imul eax, val2 ; signed multiply of val1 by val2
mov edx, OFFSET prompt
call WriteString ; Writes the prompt in edx
call WriteDec ; Writes the value in eax
ret
MultiplyAndDisplay ENDP
main PROC
call GetValue
push [intVal] ; PUSH firstParam to the stack
call GetValue
pop eax ; POP previous param/intVal to EAX
invoke MultiplyAndDisplay, eax, intVal ; MultiplyAndDisplay, firstParam(EAX), secondParam(intVal)
exit
main ENDP

masm FPU to fasm FPU cannot translate and it does not work

I have this code in masm to deal with the FPU and it works great
in this code I get a number from 2 different textboxes and then divide them and then output the results to another textbox
this is the data that is local
LOCAL variable1 :QWORD
LOCAL variable2 :QWORD
LOCAL variable3 :QWORD
LOCAL string1[20]:BYTE
LOCAL string2[20]:BYTE
LOCAL string3[20]:BYTE
this is the code
invoke GetDlgItemText,hWin,textbox1,addr string1,9
invoke StrToFloat,addr string1,addr variable1
invoke GetDlgItemText,hWin,textbox2,addr string2,9
invoke StrToFloat,addr string2,addr variable2
finit
fld variable1
fld variable2
fdiv
fstp variable3
invoke FloatToStr,variable3,addr string3
invoke SetDlgItemText,hWin,textbox3,addr string3
I am trying to convert the code to fasm
this is what I have so far but it is not working the textbox3 just says 0
this is the data (this is not local data because I have not learned how to do that in fasm yet)
v1 dq ?
v2 dq ?
v3 dd ?
v4 rb 20
this is the code
invoke GetDlgItemTextA,[hWin],textbox1,addr v1,100
invoke GetDlgItemTextA,[hWin],textbox2,addr v2,100
finit
fld qword [v1]
fld qword [v2]
fdivp
fstp qword [v3]
cinvoke wsprintfA,addr v4,"%u",[v3]
invoke SetDlgItemTextA,[hWin],textbox3,addr v4
I know this code is not right because I am not converting the text to float at the begining but i do not know how to
I also tried a simpler version and it did not work either
mov [v1],5.3
mov [v2],7.1
finit
fld [v1]
fld [v2]
fdivp
fstp [v3]
cinvoke wsprintfA,addr v4,"%u",[v3]
invoke SetDlgItemTextA,[hWin],maximumoutputpowertext,addr v4
so my question is can someone please show me how to read a number from 2 different textboxes and then divide them and the return the result to another textbox
using fasm code
thank you
There are several problems in the demonstrated code.
At first, it is not clear what StrToFloat procedure is? Is it imported from some DLL or it is part of the code, or some other library?
If this procedure is imported, it has to be imported in the FASM program as well. Else it can be written from scratch or ported in source form from the MASM program.
The immediate show stopper here is mov [v1], FLOAT_CONSTANT instruction. The reason is that v1 is qword variable, but mov can moves only dword immediate values (even in 64bit environment).
mov dword [v1], 5.0 works fine, but of course it is not what the OP needs.
Floating qword constants can be defined immediately in compile time as well: v1 dq 3.2
If we really want to set some qword floating constant in run time, we have to make it in two instructions following way:
a = 5.3
mov dword [var], (a and $ffffffff)
mov dword [var+4], (a shr 32)
var dq ?
The original FPU code in FASM syntax will be:
finit
fld [variable1]
fdiv [variable2]
fstp [variable3]

gdb break address is different when break (function name) / break *(function name)

#include <stdio.h>
int main(void){
int sum = 0;
sum += 0xabcd;
printf(“%x”, sum);
return 0;
}
This is my code and when I use gdb I can find different address when break main / break *main.
When I just type disassemble main it shows like this:
Dump of assembler code for function main:
0x080483c4 <+0>: push %ebp
0x080483c5 <+1>: mov %esp,%ebp
0x080483c7 <+3>: and $0xfffffff0,%esp
0x080483ca <+6>: sub $0x20,%esp
0x080483cd <+9>: movl $0x0,0x1c(%esp)
0x080483d5 <+17>:addl $0xabcd,0x1c(%esp)
0x080483dd <+25>:mov $0x80484c0,%eax
0x080483e2 <+30>:mov 0x1c(%esp),%edx
0x080483e6 <+34>:mov %edx,0x4(%esp)
0x080483ea <+38>:mov %eax,(%esp)
0x080483ed <+41>:call 0x80482f4 <printf#plt>
0x080483f2 <+46>:mov $0x0,%eax
0x080483f7 <+51>:leave
0x080483f8 <+52>:ret
End of assembler dump.
So when I type [break *main] it starts 0x080483c4 but type [break main] it start 0x080483cd
Why is start address is different?
Why is the address different.
Because break function and break *address are not the same thing(*address specifies the address of the function's first instruction, before the stack frame and arguments have been set up).
In the first case, GDB skips function prolog (setting up the current frame).
Total guess - and prepared to be totally wrong.
*main if address of the function
Breaking inside main is the first available address to stop inside the function when it is being executed.
Note that 0x080483cd is the first place a debugger can stop as it is modifying a variable (ie assigning zero to sum)
When you are breaking at 0x080483c4 this is before the setup assembler that C knows nothing about

Resources