flat assembler
Message board for the users of flat assembler.

Index > Windows > about fasm and sqlite ?

Author
Thread Post new topic Reply to topic
senolc_eht



Joined: 22 Mar 2004
Posts: 57
Location: Indonesia
senolc_eht
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)


Description:
Download
Filename: console.zip
Filesize: 206.78 KB
Downloaded: 121 Time(s)


_________________
sorry if i always asking.....
Post 22 Jan 2008, 00:21
View user's profile Send private message Yahoo Messenger Reply with quote
farrier



Joined: 26 Aug 2004
Posts: 274
Location: North Central Mississippi
farrier
senolc_eht,

You will have to use the cinvoke macro, instead of the invoke macro when calling any of the sqlite3 functions. You can verify this by comparing esp before and after the call to these functions. This may get you started.

Code:
cinvoke sqlite3_open,filename,ppdB
    

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!
Post 22 Jan 2008, 01:47
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
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)
Post 22 Jan 2008, 01:53
View user's profile Send private message Reply with quote
farrier



Joined: 26 Aug 2004
Posts: 274
Location: North Central Mississippi
farrier
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!
Post 22 Jan 2008, 03:42
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
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"
Post 22 Jan 2008, 04:01
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17665
Location: In your JS exploiting you and your system
revolution
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.
Post 22 Jan 2008, 05:04
View user's profile Send private message Visit poster's website Reply with quote
farrier



Joined: 26 Aug 2004
Posts: 274
Location: North Central Mississippi
farrier
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!
Post 22 Jan 2008, 07:12
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
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]
Post 22 Jan 2008, 13:02
View user's profile Send private message Reply with quote
farrier



Joined: 26 Aug 2004
Posts: 274
Location: North Central Mississippi
farrier
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!
Post 22 Jan 2008, 16:44
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
Quote:

The esp is the same either way, before and after the sqlite3_exec

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.
Post 22 Jan 2008, 17:11
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
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    
(I didn't check if paths are always quoted so I kept the space scan code to be safe)

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    
(remember to download senolc_eht's attachment and replace console.ASM with this new code)
Post 22 Jan 2008, 19:12
View user's profile Send private message Reply with quote
farrier



Joined: 26 Aug 2004
Posts: 274
Location: North Central Mississippi
farrier
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
Post 22 Jan 2008, 21:14
View user's profile Send private message Reply with quote
senolc_eht



Joined: 22 Mar 2004
Posts: 57
Location: Indonesia
senolc_eht
Every body thanks for the help it's now work fine.

LocoDelAssembly thanks for the parser code Smile

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.....
Post 23 Jan 2008, 00:37
View user's profile Send private message Yahoo Messenger Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.