Valhalla Legends Forums Archive | Assembly Language (any cpu) | The VB Reversing Reference Thread

AuthorMessageTime
TheMinistered
NOTE: The functions were located & tested inside an object.
Additionally, the offsets from ebp I provided might not be the same in all situations

*Returning a long

Parameter with double pointer to return
Local Variable to hold data assigned to be returned

Example:
[code]
Public Function Test() as Long
   Test = 20 'local variable
End Function
[/code]

EBP+0C = Double pointer to return
EBP-18 = Local variable to hold data to be returned


*Returning an integer

Parameter with double pointer to return
Local Variable to hold data assigned to be returned

Example:
[code]
Public Function Test() as Integer
   Test = 20 'local variable
End Function
[/code]

EBP+0C = Double pointer to return
EBP-18 = Local variable to hold data to be returned

*Returning an boolean

Parameter with double pointer to return
Local Variable to hold data assigned to be returned

Example:
[code]
Public Function Test() as Boolean
   Test = True 'local variable
End Function
[/code]

EBP+0C = Double pointer to return
EBP-18 = Local variable to hold data to be returned

Additional Notes: Visual basic uses -1 for true and 0 for false

*Returning an byte

Parameter with double pointer to return
Local Variable to hold data assigned to be returned

Example:
[code]
Public Function Test() as Byte
   Test = 20 'local variable
End Function
[/code]

EBP+0C = Double pointer to return
EBP-18 = Local variable to hold data to be returned


*Returning an double

Parameter with double pointer to return
Local Variable to hold data assigned to be returned

Example:
[code]
Public Function Test() as Double
   Test = 20 'local variable
End Function
[/code]

EBP+0C = Double pointer to return
[[RETURN]] = High Dword
[[RETURN+4]] = Low Dword

EBP-1C = Local variable to hold data to be returned
[LOCAL] = High Dword
[LOCAL+4] = Low Dword

Additional Notes: The visual basic double data type follows the IEEE double precision floating point standard


*Returning an single

Parameter with double pointer to return
Local Variable to hold data assigned to be returned

Example:
[code]
Public Function Test() as Single
   Test = 20 'local variable
End Function
[/code]

EBP+0C = Double pointer to return
EBP-18 = Local variable to hold data to be returned

Additional Notes: The visual basic single data type follows the IEEE single precision floating point standard

*Returning a currency

Parameter with double pointer to return
Local Variable to hold data assigned to be returned

Example:
[code]
Public Function Test() as Curreny
   Test = 20 'local variable
End Function
[/code]

EBP+0C = Double pointer to return
[[RETURN]] = Low Dword
[[RETURN+4]] = High Dword

EBP-1C = Local variable to hold data to be returned
[LOCAL] = Low Dword
[LOCAL+4] = High Dword

Additional Notes: The visual basic currency data type follows an unknown standard, perhaps put forth by microsoft.
February 23, 2004, 12:02 AM
TheMinistered
This is a typical string comparison programmers in vb6 will use, look out for this

[code]
;...
push offset string1
push offset string2
push 0
;...
call __vbaStrComp
not eax
test ax, ax
;...
je NotMatch
[/code]

This block of code pushes two strings, and the comparison type to use then calls __vbaStrComp.
__vbaStrComp returns zero if it's a match. This is why the programmer will not it and then do:

[code]
If Return = True Then
'match
else
'not match
end if
[/code]

If they do not perform some sort of not on the return then the if structure looks like this:
[code]
If Return = False Then
'not match
else
'match
End if
[/code]
February 23, 2004, 12:30 AM
TheMinistered
If the vb6 function is located in an object, the params will look like this:

[code]
;nasm syntax
%define return_caller [esp+04h]
%define this [esp+08h]
;...
%define returnvalue [esp+0Ch]
[/code]

Where this and return are both double pointers, correct me if i'm wrong. If you have additional parameters to the function then you need to adjust the return offset.

note: this is the equivalent of the me object
note: eax is used to return the hresult, thus functions must return values over the stack
February 23, 2004, 1:07 AM
TheMinistered
Here is a watered down version of how visual basic handles a simplistic for/next loop.

Visual Basic code located in a form
[code]
Private Sub Form_Load()
  Dim intCounter as Integer, i as Integer

    For intCounter = 1 to 100
        i = i + 1
    Next intCounter
End Sub
[/code]



Watered down assembly listing
[code]
; Dim intCounter As Integer, i As Integer
; ...
; For intCounter = 1 To 100
mov eax, 1

$FORLOOPHEAD:
; i = i + 1
add cx, 1
jo SHORT $ERROROVERFLOW
add ax, 1
jo SHORT $ERROROVERFLOW

; Next intCounter
cmp ax, 100 ; 00000064H
jle SHORT $FORLOOPHEAD

; ...

$ERROROVERFLOW:
call DWORD PTR __imp____vbaErrorOverflow

; ...
; End Sub
[/code]

Note:  This also points out a potential optimization that should be taken into consideration by all developers:  Use the appropriate data type for the amount of cycles through the for/next loop that are expected.  i.e. if you need the for loop to cycle from 1 to 100 don't use an integer, use a byte.  Thus, it wouldn't use ax/cx for adding, but rather al/cl.  On second hand, using eax/ecx for adding might always be faster, I don't know-- if that be the case it would be to your advantage to always use a long data type for counters.  Anyone have a thought on this?
December 5, 2004, 5:26 PM
BreW
Is this how an api call is made?

[code]
.text:00405348 aGetprivateprof db 'GetPrivateProfileStringA',0 ; DATA XREF: .text:00405368o
.text:00405361                 align 4
.text:00405364 off_405364      dd offset aKernel32     ; DATA XREF: GetPrivateProfileStringA:loc_405387o
.text:00405364                                         ; "kernel32"
.text:00405368                 dd offset aGetprivateprof ; "GetPrivateProfileStringA"
.text:0040536C                 align 10h
.text:00405370                 dd offset unk_4193BC
.text:00405374                 dd 2 dup(0)


....

.text:0040537C ; DWORD __stdcall GetPrivateProfileStringA(LPCSTR lpAppName,LPCSTR lpKeyName,LPCSTR lpDefault,LPSTR lpReturnedString,DWORD nSize,LPCSTR lpFileName)
.text:0040537C GetPrivateProfileStringA proc near      ; CODE XREF: sub_417520+14Dp
.text:0040537C                 mov     eax, dword_4193C4
.text:00405381                 or      eax, eax
.text:00405383                 jz      short loc_405387
.text:00405385                 jmp     eax
.text:00405387 ; ---------------------------------------------------------------------------
.text:00405387
.text:00405387 loc_405387:                             ; CODE XREF: GetPrivateProfileStringA+7j
.text:00405387                 push    offset off_405364
.text:0040538C                 mov     eax, offset DllFunctionCall
.text:00405391                 call    eax ; DllFunctionCall
.text:00405393                 jmp     eax
.text:00405393 GetPrivateProfileStringA endp
[/code]
Also, i've noticed that they're not called by any definate functions. how does vb6 store/call functions and call event subs?
March 23, 2008, 8:07 PM
l2k-Shadow
i thought api calls were made through msvbvm60.dll, not directly from the exe? but i could be wrong.
March 23, 2008, 9:11 PM
BreW
[quote author=l2k-Shadow link=topic=5409.msg177238#msg177238 date=1206306690]
i thought api calls were made through msvbvm60.dll, not directly from the exe? but i could be wrong.
[/quote]
They are. hence "DllFunctionCall".
March 23, 2008, 9:16 PM

Search