flat assembler
Message board for the users of flat assembler.
Index
> Windows > about fasm and sqlite ? |
Author |
|
senolc_eht 22 Jan 2008, 00:21
I make an console program that can use to send sql command to access the sqlite database:
Code: ; ; examples use "console.exe select * from tbl1" ; format PE console entry start include 'win32a.inc' section '.data' data readable writeable stdOut dd ? test1 db 'antony',0 writehlk dd ? dump rb 1000h samadengan db ' = ',0 enter1 db 13,10,0 ;===sqlite ppdB dd ? filename db 'faktur.db',0 sqlexec dd ? ;sqlexec db 'select * from faktur',0 error dd ? error2 dd ? ;== end sqlite section '.code' code readable executable start: invoke GetStdHandle,STD_OUTPUT_HANDLE ; get standard output handle mov [stdOut],eax ; stdOut = standard output handle invoke GetCommandLine ; get commandline stdcall parse,eax ; parse commandline mov [sqlexec],eax ;sqlexec = address of sql command invoke sqlite3_open,filename,ppdB ; open faktur.db cmp eax,0 jnz .error invoke sqlite3_exec, [ppdB],[sqlexec],loginproc,NULL,error ; execute sqlcommand in [sqlexec] cmp eax,0 jnz .error invoke sqlite3_free,[error] ; freeing error memory ? invoke sqlite3_close,[ppdB] ; close faktur.db jmp .finish .error: ; sqlite error handle invoke sqlite3_errmsg,[ppdB] ; get error message mov [error2],eax invoke lstrlen,eax invoke WriteFile,[stdOut],[error2],eax,writehlk,NULL ; show error message invoke sqlite3_close,[ppdB] ; close data base .finish: invoke ExitProcess,0 ; exit program proc parse,text ; parse commandline assume "console.exe select * from tbl1" mov esi,[text] .loop1: lodsb cmp al,20h ;if al = space then end loop je .param jmp .loop1 .param: mov eax,esi ret endp proc loginproc, notused, argc, argv, azcolname ; sqlite callback push ebx esi edi ; save ebx esi edi mov ecx, [argc] ; get number of coloum mov ebx,[argv] ; begining of coloum value mov eax,[ebx] ; first coloum value push ecx ; save ecx to stack mov byte [dump],0 ; make sure dump is empty invoke lstrcpy,dump,eax ; add first coloum value to dump pop ecx ; restore ecx from stack dec ecx ; subtitute ecx with 1 cmp ecx,0 ; if ecx = 0 then skiploop jz .skiploop .loop1: push ecx ; save ecx for loop invoke lstrcat,dump,samadengan ; add dump with ' = ' add ebx,4 ; get next coloum value address mov eax,[ebx] ; eax = coloum value address invoke lstrcat,dump,eax ; add dump with text in eax pop ecx ; restore ecx for loop loop .loop1 .skiploop: invoke lstrcat,dump,enter1 ; add dump with char 13,10 (enter) invoke lstrlen,dump ; get dump size invoke WriteFile,[stdOut],dump,eax,writehlk,NULL ; send dump to std output pop edi esi ebx ; restore edi esi ebx xor eax,eax ;emptying eax (eax=1 sqlite assume there's an error) ret ; return to sqlite endp section '.idata' import data readable writeable library kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL',\ gdi32, 'GDI32.dll',\ comdlg32, 'COMDLG32.DLL',\ comctl32, 'COMCTL32.DLL',\ sqlite3,"sqlite3.dll",\ msvcrt,'msvcrt.dll' include 'api\kernel32.inc' include 'api\user32.inc' include 'api\gdi32.inc' include 'api\comdlg32.inc' include 'api\comctl32.inc' include 'sqlite3.inc' import msvcrt,\ getchar,'getchar',\ printf,'printf' but when i send "select * from tbl1" when the record more then tree this program crashing, and i can't found which one that make it crash. can some one tell me what's wrong with my code? regard Senolc_eht PS : I attach the zip file of all file needed by this code. (including sqlite3.dll)
_________________ sorry if i always asking..... |
|||||||||||
22 Jan 2008, 00:21 |
|
LocoDelAssembly 22 Jan 2008, 01:53
Then is very possible that loginproc is wrong too, you should use "proc loginproc c, notused, argc, argv, azcolname"
http://flatassembler.net/docs.php?article=win32 (Especially check 1.3 Procedures) |
|||
22 Jan 2008, 01:53 |
|
farrier 22 Jan 2008, 03:42
There is no need to declare the callback function as a 'c' proc,
hth, farrier _________________ Some Assembly Required It's a good day to code! U.S.Constitution; Bill of Rights; Amendment 1: ... the right of the people peaceably to assemble, ... The code is dark, and full of errors! |
|||
22 Jan 2008, 03:42 |
|
LocoDelAssembly 22 Jan 2008, 04:01
Why not? If the callback is not stdcall then the arguments will be freed twice causing important stack unbalancing and possibly destroying any chance for the caller of the callback to return.
PS: "ret" inside a stdcall proc is in fact "leave/retn args*4" |
|||
22 Jan 2008, 04:01 |
|
revolution 22 Jan 2008, 05:04
Yes, I think that farrier's comment my be in error. sqlite is all c and the callbacks would most likely be expected to be c style also.
|
|||
22 Jan 2008, 05:04 |
|
farrier 22 Jan 2008, 07:12
This is my opinion, (me, assuming thru observation:)
The callback function is defined by me--the user--not sqlite. As you can see by senolc_eht 's code, the function is a standard stdcall function called by sqlite, the stack is balanced by this callback function, and should not require balancing by caller. I have verified this in my own program by monitoring the stack pointer before, during, and after the callback function. end of my opinion... farrier _________________ Some Assembly Required It's a good day to code! U.S.Constitution; Bill of Rights; Amendment 1: ... the right of the people peaceably to assemble, ... The code is dark, and full of errors! |
|||
22 Jan 2008, 07:12 |
|
LocoDelAssembly 22 Jan 2008, 13:02
Code: .text:6092EF3B mov ecx, [ebp+arg_8] .text:6092EF3E call ecx .text:6092EF40 add esp, 10h .text:6092EF43 test eax, eax .text:6092EF45 jnz loc_6092EDFC That comes from sqlite_exec (note that Ida numerates the args according to the distance in bytes to the first argument so this is argument 3). How did you verified the balancing? Did you also trace the DLL? Because perhaps your code survived because the double args release only affected the local vars of sqlite_exec so when this one executes "leave" ESP is rebalanced again but the problem is that the local vars are used again in a few more calls (sqlite_finalize and sqlite_free for example), and very probably both functions fails but don't crash. As a general note, it doesn't matter who defines the functions, you must make sure that your caller will match with your defined calling convention. [edit]BTW, I'm wrong about the local vars since those are addressed via EBP but in every call to a function will destroy 16 bytes of local vars space at most, and if the callback is called many times it starts to put in risk the return address and anything the caller of the DLL has on the stack (stack frames, ret addresses, etc). This could be the reason as for why he start to see problems when three records (and more?) are returned.[/edit] |
|||
22 Jan 2008, 13:02 |
|
farrier 22 Jan 2008, 16:44
LocoDelAssembly,
Oddly enough, it doesn't seem to matter whether the callback is defined as stdcall or c . The esp is the same either way, before and after the sqlite3_exec . I found within the sqlite3_exec routine where my callback is called, and there is some weird stuff going on in there. If I get more time, I'll try to find out how this happens, but it appears that sqlite3_exec balances the stack to avoid any confusion. thanks for the info! farrier _________________ Some Assembly Required It's a good day to code! U.S.Constitution; Bill of Rights; Amendment 1: ... the right of the people peaceably to assemble, ... The code is dark, and full of errors! |
|||
22 Jan 2008, 16:44 |
|
LocoDelAssembly 22 Jan 2008, 17:11
Quote:
Because of what I've said, executing "leave" is equivalent to "mov esp, ebp / pop ebp" so of course at return of sqlite_exec you have the same ESP value. The problem arises if the callback is called many times starting from the second call to Nth it will destroy 16 bytes of stack per call so if it is called too many then it will destroy the return address, the oldEBP save area, etc, etc, etc. And note that actually even if the callback is called once you are still in trouble since EBX, ESI and EDI are restored before issuing "leave" so you could verify the unbalancing problem by checking that those registers loose their original values when you return from sqlite_exec and hence violates the calling convention. |
|||
22 Jan 2008, 17:11 |
|
LocoDelAssembly 22 Jan 2008, 19:12
senolc_eht, use this code to get the arguments instead since yours doesn't work if the path has spaces somewhere (since I depacked it on my Desktop it never worked because the full path is C:\Documents and Settings\...", the space after "Documents" is enough to make your proc fail).
Code: parse_args: invoke GetCommandLine cmp byte [eax], '"' je .skip_quoted_path .scan_space: inc eax cmp byte [eax], ' ' jne .scan_space ret .skip_quoted_path: inc eax cmp byte [eax], '"' jne .skip_quoted_path inc eax ret farrier, try this minimal code in OllyDbg: Code: CONVENTION equ stdcall ;CONVENTION equ c format PE gui include 'win32ax.inc' cinvoke sqlite3_open,filename,ppdB ; open faktur.db mov ebx, $DEADBEEF mov esi, ebx mov edi, ebx cinvoke sqlite3_exec, [ppdB], sqlexec, loginproc, NULL, dummy ; execute sqlcommand in [sqlexec] int3 ; EBX = ESI = EDI = 0xDEADBEEF only if CONVENTION is c proc loginproc CONVENTION, notused, argc, argv, azcolname ; sqlite callback or eax, -1 ; one shot only to prevent program crashes with stdcall convention ; xor eax, eax ; uncomment to crash the program when CONVENTION is stdcall ret endp ;===sqlite ppdB dd ? filename db 'faktur.db',0 sqlexec db 'select * from tbl1',0 ;== end sqlite align 4 data import library sqlite3,"sqlite3.dll" include 'sqlite3.inc' end data dummy rd 1 |
|||
22 Jan 2008, 19:12 |
|
farrier 22 Jan 2008, 21:14
LocoDelAssembly,
You are correct! Thanks, I was not looking at the problem correctly! It's just amazing that my program was not crashing with the callback set up incorrectly. Dumb luck I guess. farrier I found the source of my confusion. I originally used the sqlite3_exec to execute the PRAGMA integrity_check; command. And when I studied the handling of the callback, the callback function was being called 5 times--for different parts of the integrity check--and each time the callback was called, the stack pointer never changed. I don't understand why. But when I used sqlite3_exec to select all records of a table, the lack of stack correction reared its' evil head. Thanks again. _________________ Some Assembly Required It's a good day to code! U.S.Constitution; Bill of Rights; Amendment 1: ... the right of the people peaceably to assemble, ... The code is dark, and full of errors! Last edited by farrier on 23 Jan 2008, 03:31; edited 1 time in total |
|||
22 Jan 2008, 21:14 |
|
senolc_eht 23 Jan 2008, 00:37
Every body thanks for the help it's now work fine.
LocoDelAssembly thanks for the parser code regard Senolc_eht PS: Out of topic is there any way to load flash movie in assembly, and control it. _________________ sorry if i always asking..... |
|||
23 Jan 2008, 00:37 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.