Disasm Visual Basic Applications PDF
Disasm Visual Basic Applications PDF
*
DISASSEMBLING VISUAL BASIC APPLICATIONS
*
*
- Sanchit Karve
*
*
*
*
born2c0de
*
*
printf("I'm a %XR",195936478);
*
*
*
*
CONTACT ME :
born2c0de AT hotmail DOT com
*
*
*
********************************************************************************
LAST UPDATED :
26 JULY 2006
INDEX [INDX]
I.
II.
III.
IV.
V.
VI.
VII.
VIII.
IX.
X.
XI.
I.
[DISN]
[RTUT]
[ITRO]
[ASPT]
[RQRT]
[SVBP]
[OFPR]
[STR1]
[END1]
[NXTU]
[REFR]
The information provided in this tutorial must not be used for Reverse
Engineering any application.
THE TEXT HAS BEEN WRITTEN IN SUCH A WAY THAT THE READER CAN LEARN, AND NOT JUST
GAIN INFORMATION WITHOUT KNOWING HOW STUFF WORKS.
If the Reader still chooses to break Protection Mechamisms after reading this
tutorial, he/she shall alone be responsible for the damages cause and not the
Author.
If you wish to post certain Sections of the Tutorial on a Website, you are free
to do so provided you inform the author and publish the Selected Text from the
Tutorial as it is without modification.
The Author has not copied text or any other information directly from a Source.
However, some information from some sources has been used to write this tutorial.
These Sources have been mentioned in the References Section.
You are permitted to continue reading the tutorial only if you agree to the text
given above.
IV.
ASSUMPTIONS [ASPT]
You are required to have a basic understanding of Visual BASIC,C,the Windows API
and 80x86 Microprocessor Assembly Language.
It would be advisable to have a copy of Intel's 80x86 Instruction Set Manual.
Intel provides this manual free of charge. If you need this manual, contact me.
This Instruction Set Reference is Volume 2 of Intel Architecture Software
Developer's Manual.
The Software Developer's Manual consists of 3 volumes:
: Basic Architecture
- Order Number 243190
: Instruction Set Reference - Order Number 243191
: System Programming Guide - Order Number 243192
You can provide these Order Numbers to get a copy of these manuals. For this
tutorial only Volume 2 is required.
V.
You will need the following tools to proceed with the Tutorial.
*
*
*
*
*
*
*
COMPILER
: Visual Basic 6.0
DISASSEMBLER : IDA Pro 4.x or higher
DEBUGGER
: OllyDebug Ver. 1.09d or higher
WINDOWS API DOCUMENTATION
NuMeGa SmartCheck 6.x
VBDE version 0.85 by iorior
VBReformer
VBDE is not required but it's always better to have it as it gives addresses of
entry-points of most VB procedures.
VBReformer is used to see the Property values of all objects in a Visual Basic
Form. It even allows you to change the value of Object Properties such as Forms,
Command Buttons etc. Import Libraries can also been seen. This Application is
not required for this Tutorial but it's better to have it.
NuMeGa SmartCheck is again not required but it is useful when we have no idea
what a particular procedure of VB does. You can run a program from it like a
Debugger and view its log files and find out which procedure is called and what
operations are carried out etc.
You can have API Documentation from MSDN or you can use the API Text Viewer Tool
supplied with Visual Studio or browse MSDN Online (msdn.microsoft.com). Certain
Applications like APIViewer will also do.
I have given the names of the Tools that I have used. But you are free to use
any disassembler and debugger as long as you are comfortable using it but I
advice you to use the tools that I have used above. SoftIce is better than
OllyDebug but the latter is good enough for VB Programs so it doesn't matter
which one you use.
Once you have the necessary knowledge and tools, you can proceed further.
Let's begin.
Let us now start analysis from the entry point of the program.
push
offset RT_Struct
call
ThunRTMain
proc near
arg_0
= dword ptr
mov
mov
and
lea
push
lea
push
call
movzx
mov
push
push
mov
mov
call
mov
test
jl
push
push
push
call
push
call
; Other
esi, [ebp+arg_0]
dword_7352F7DC, esi
[ebp+var_4], 0
eax, [ebp+StartupInfo]
eax
; lpStartupInfo
eax, [ebp+StartupInfo]
eax
; lpStartupInfo
ds:GetStartupInfoA
eax, [ebp+StartupInfo.wShowWindow]
dword_7352F7D8, eax
hModule
esi
esi, offset dword_7352F470
ecx, esi
sub_7342DECD
[ebp+var_1C], eax
eax, eax
short loc_7342DEC5
0
; lParam
0
; wParam
1069h
; Msg
ds:GetCurrentThreadId
eax
; idThread
ds:PostThreadMessageA
Code
or
push
call
jmp
[ebp+var_4], 0FFFFFFFFh
0
; uExitCode
ds:ExitProcess
loc_734619B3
push
call
jmp
loc_7342DEC5:
endp
As you can see, it does call all the Functions that the start() function does in
C and PASCAL programs. But what about CommandLine() Function from KERNEL32.DLL?
MSVBM60.DLL does call that function as well but that function call is placed in
deeply nested function calls. You can open the Imports Window to see the
Imported Function and see the cross-reference to a procedure in MSVBM60.DLL
The sub_Free_Memory procedure calls various API Functions but if you keep
reading the procedure, you'll soon come across the HeapFree() Function which is
imported from kernel32.dll.
Now I guess you now know the purpose of the ThunRTMain Function.
Let us now see what structure is passed to it.
If we double-click on the RT_Struct offset, we reach an address containing
certain values.
It is a huge structure and each part needs to be seen one at a time.
Explaining the Structure will take up a lot of time and since I want to focus on
the Code Constructs of Visual BASIC, I won't explain the Structure Passed to
ThunRTMain.
All I can tell you is that the structure contains the PE (Portable Executable)
Header Details. It is this header that is read by Resource Editors.
I found a good source for understanding the structure that is passed to
ThunRTMain and I suggest you read it if you are interested in knowing PE Header
Details. The link to the Article is given in the References [REFR] Section. The
article is titled "VISUAL BASIC REVERSED - A decompiling approach" and is
written by Andrea Geddon.
If the link is dead by the time you are reading this, you can contact me on my
email address to get the article.
VII.
Create a Form with a CommandButton. Click the CommandButton and add a simple
Msgbox Code as shown below:
Private Sub Command1_Click()
Msgbox "Ssup"
End Sub
Open the Compiled EXE File with IDA Pro.
Click the Strings Tab to find the "Ssup" String.
Double-Click the String to find its cross-reference.
Scroll up to the top of the procedure.
You should see something like this:
[Explanation is partly given by comments after an instruction.]
Command1_Click
var_64
var_5C
var_54
var_4C
var_44
var_3C
var_34
var_2C
var_24
var_14
var_C
var_8
var_4
form_object
proc near
=
=
=
=
=
=
=
=
=
=
=
=
=
=
dword
dword
dword
dword
dword
dword
dword
dword
dword
dword
dword
dword
dword
dword
ptr
ptr
ptr
ptr
ptr
ptr
ptr
ptr
ptr
ptr
ptr
ptr
ptr
ptr
-64h
-5Ch
-54h
-4Ch
-44h
-3Ch
-34h
-2Ch
-24h
-14h
-0Ch
-8
-4
8
; Destructor Object
push
mov
sub
push
mov
push
mov
sub
push
push
push
ebp
; These two instructions
ebp, esp
; open the Stack Frame.
esp, 0Ch
; Allocates 12 bytes on stack
(offset exception_handler+1); Starts Exception Handler
eax, large fs:0
eax
large fs:0, esp
esp, 88h
; Allocates 136 bytes on stack
ebx
esi
; Saves Values of Registers
edi
mov
mov
mov
mov
and
mov
and
push
mov
mov
call
mov
xor
mov
mov
mov
mov
mov
mov
mov
mov
lea
lea
mov
mov
mov
mov
mov
mov
call
lea
lea
push
lea
push
push
lea
push
push
call
lea
lea
push
lea
push
lea
push
push
push
call
add
mov
push
jmp
ds:__vbaFreeVarList
esp, 14h
[ebp+var_4], esi
offset continue_after_jump
short fake_a_call_instr
lea
edx, [ebp+var_54]
lea
eax, [ebp+var_44]
push
edx
lea
ecx, [ebp+var_34]
push
eax
lea
edx, [ebp+var_24]
push
ecx
push
edx
push
4
call
ds:__vbaFreeVarList
add
esp, 14h
retn
; --------------------------------------------------------------------------fake_a_call_instr:
retn
; --------------------------------------------------------------------------continue_after_jump:
mov
push
mov
call
mov
mov
pop
pop
mov
pop
mov
pop
retn
Command1_Click endp
eax, [ebp+arg_0]
eax
ecx, [eax]
dword ptr [ecx+8]
eax, [ebp+var_4]
ecx, [ebp+var_14]
edi
esi
large fs:0, ecx
ebx
esp, ebp
ebp
4
; Calls MSVBM60.Zombie_Release
Simply by looking at the entire procedure you can't exactly figure out what the
hell happens when the whole subroutine is executed. If you know Assembly well
and have had the patience to read through the code, you should notice a few neat
things in the code.
[XTRA]
Before I begin explaining the procedure, I want to teach you how to recognise a
procedure in Visual BASIC. They can be called Procedure Signatures.
1) A Procedure has the open and close Stack Frame instructions.
2) The First Procedure in a VB Program is always preceded by
12 0xCC Bytes (which corresponds to the INT 3 Instruction) followed by
4 'T' bytes (0xE9) followed by 12 0xCC bytes.
3) Procedures other than the first are preceded by 10 NOP(0x90) Instructions.
: 1) STACK FRAME:
The Open/Close Stack Frame Instructions are even found in C/C++ and Pascal
programs and hence can be termed as a universal method of determining procedures.
However that is not always the case.
--> Many compilers just JMP instructions to fake a Call Instruction. This Jump
is at times a CALL to a procedure. IDA Pro does not detect such
To do that, start OllyDebug and load the Executable file by pressing F3.
After the program is loaded, press Alt+E to open the Executable Modules Window.
Double click USER32.DLL to open the disassembled listing of the User32.dll file.
From there press Ctrl+N to open the Imports/Exports Window. Then Scroll over
till you see the MessageBoxA and MessageBoxW Functions. Click them one at a time
and press F2 to set a breakpoint.
Now press F9 to run the program. The Application should open. Click the
CommandButton. Now instead of the Debugger halting at a breakpoint of MessageBox,
the MessageBox comes up without any halt to the Debugger.
Why does this happen? Does this mean that rtcMsgBox has a seperate copy of the
MessageBox code within itself? Though it seems like a possible reason, it is
unlikely to happen as Microsoft Developers built the Windows API so that they
could be reused for performance. So that means that some API Function is called
which displays the MessageBox.
So let us try another experiment. In the same Imports/Exports Section of
User32.dll we see 2 more MessageBox functions which are MessageBoxIndirectA and
edx, [eax]
[ebp+hWnd.lpszText], ecx
ecx, [eax+8]
eax, [eax+0Ch]
esi
ebx
ah, 40h
[ebp+hWnd.hInstance], edi
[ebp+hWnd.lpszIcon], edi
[ebp+hWnd.lpfnMsgBoxCallback], edi
[ebp+hWnd.cbSize], 28h
[ebp+hWnd.hwndOwner], edx
[ebp+hWnd.lpszCaption], ecx
[ebp+hWnd.dwStyle], eax
[ebp+hWnd.dwLanguageId], edi
short loc_734A6133
[ebp+hWnd.lpfnMsgBoxCallback], offset sub_734A6098
loc_734A6133:
mov
esi, ds:MessageBoxIndirectA
lea
push
call
eax, [ebp+hWnd]
eax
; LPMSGBOXPARAMSA
esi ; MessageBoxIndirectA
__vbaFreeVarList
ecx, [ebp+var_54] ;
edx, [ebp+var_44] ;
ecx
;
eax, [ebp+var_34] ;
edx
;
ecx, [ebp+var_24] ;
eax
;
ecx
;
4
;
ds:__vbaFreeVarList
The code is pretty easy to understand. This function frees temporary variables
that are passed as arguments to it.Interestingly each memory location is
16 bytes wide.
This is an interesting function as it can accept variable arguments.
It's equivalent function call in C would be:
__vbaFreeVarList(4,&var_24,&var_34,&var_44,&var_54);
where its declaration would be:
int __vbaFreeVarList(int NUMBER_OF_VARIABLES_TO_FREE,<addresses of the vars>...)
{
// CODE
}
If we analyse the code of __vbaFreeVarList, we actually find multiple calls of
__vbaFreeVar. Have a look at the source code of __vbaFreeVarList.
public __vbaFreeVarList
__vbaFreeVarList proc near
arg_0
arg_4
arg_8
= dword ptr
= dword ptr
= dword ptr
mov
push
lea
call
4
8
0Ch
ecx, [esp+arg_4]
esi
esi, [esp+4+arg_8]
__vbaFreeVar
;
;
;
;
mov
cmp
jbe
push
lea
eax, [esp+arg_4]
;
;
eax, 1
;
short freed_all_vars ;
edi
;
edi, [eax-1]
;
while(edi){ /*CODE*/ }
loop_start:
mov
add
call
dec
jnz
ecx, [esi]
esi, 4
__vbaFreeVar
edi
short loop_start
pop
edi
;
;
;
;
;
;
;
;
;
;
freed_all_vars:
pop
esi
retn
ENGINE:7352009D __vbaFreeVarList endp
As you can see, __vbaFreeVarList uses a while loop to free each variable one by
one using the __vbaFreeVar Function.
Notice that the address of the variable to be freed is stored in ECX always.
You can disassemble the __vbaFreeVar Function to confirm that.
Now let us see what happens when after the MessageBox is shown.
This is the most interesting part.
After the MessageBox is displayed, a clean up code is executed that deallocates
all the variables used in the entire procedure. Have a look at these statements
in the Command1_Click() Code.
push
offset continue_after_jump
jmp
short fake_a_call_instr
; --------------------------------------------------------------------------fake_a_call_instr:
retn
; --------------------------------------------------------------------------continue_after_jump:
; code
This is the 'CALL-Simulation' instruction. If you recall, before a call function
is executed, the processor pushes the location of the instructions which are
supposed to receive control after execution of a function is over.
VB instead of issuing a call instruction simulates it using the push, jmp and
retn instructions. It is small sections of code like this that reduce Visual
BASIC's efficiency and performance.
Let us still see why this is done.
The CALL-Simulation Instruction calls the MSVBM60.Zombie_Release function.
This is the destructor code. Doesn't that remind you of something?
The instruction
mov
[ebp+var_8], offset destructor
contains the offset of the destructor code. But is this so?
Double-click on the 'offset destructor' text and you'll land up here.
destructor
Hmm...this contains more offsets? By simply double-clicking the offsets you land
up at the destructor code again. That's why the CALL simulation code is used so
that the destructor code looks like its an inline function.
If you're more curious, you can also double-click the 'exception_handler' text
to see where that leads to.
Well, after a long journey into the Command1_Click() Procedure, we're finally
done analyzing it.
From this point onwards, I shall explain only the important section of code
rather than explain such intricate details once again.
Let us proceed further.
This Time let us create a Visual BASIC Application using only a module.
We shall use the Main Subroutine.
Use this code:
Sub Main()
MsgBox "Ssup"
End Sub
What you will realise that the Procedure code is an exact copy of the code we
dealt with earlier. This means that Form Procedures and Module Procedures are
treated alike. This also means that the Command Button code procedure had no
chance of using any information of the Form Object.
Let's take another example.
VIII.
Create a form without any controls. The code in the form module is as follows:
Private Sub Form_Load()
If "Sanchit" <> InputBox("ssup") Then
MsgBox "wrong"
Else
MsgBox "Right"
End If
End Sub
The resultant code is shown below (after stripping unimportant instructions)
Form_Load
proc near
; Variables and Arguments shown
push
mov
sub
ebp
ebp, esp
esp, 0Ch
push
mov
push
mov
sub
push
push
push
mov
mov
mov
mov
and
mov
and
push
mov
mov
call
xor
mov
mov
(offset vba_exception_handler+1)
eax, large fs:0
eax
large fs:0, esp
esp, 0F0h
ebx
esi
edi
[ebp+var_C], esp
[ebp+var_8], offset destructor
eax, [ebp+arg_0]
ecx, eax
ecx, 1
[ebp+var_4], ecx
al, 0FEh
eax
[ebp+arg_0], eax
edx, [eax]
dword ptr [edx+4] ; Zombie_AddRef()
eax, eax
ebx, 80020004h
edi, 0Ah
; code...
lea
lea
edx, [ebp+var_98]
ecx, [ebp+var_28]
lea
push
lea
push
lea
push
lea
push
lea
push
lea
push
push
ecx,
eax
edx,
ecx
eax,
edx
ecx,
eax
edx,
ecx
eax,
edx
eax
call
mov
lea
call
push
call
mov
lea
neg
sbb
neg
neg
call
lea
ds:rtcInputBox
edx, eax
ecx, [ebp+var_18]
ds:__vbaStrMove
eax
ds:__vbaStrCmp
esi, eax
ecx, [ebp+var_18]
esi
esi, esi
esi
esi
ds:__vbaFreeStr
ecx, [ebp+var_88]
[ebp+var_78]
[ebp+var_68]
[ebp+var_58]
[ebp+var_48]
[ebp+var_38]
[ebp+var_28]
lea
edx, [ebp+var_78]
push
ecx
lea
eax, [ebp+var_68]
push
edx
lea
ecx, [ebp+var_58]
push
eax
lea
edx, [ebp+var_48]
push
ecx
push
edx
lea
eax, [ebp+var_38]
lea
ecx, [ebp+var_28]
push
eax
push
ecx
push
7
call
ds:__vbaFreeVarList
add
esp, 20h
mov
[ebp+var_50], ebx
test
si, si
mov
[ebp+var_58], edi
mov
[ebp+var_40], ebx
mov
[ebp+var_48], edi
mov
[ebp+var_30], ebx
mov
[ebp+var_38], edi
jz
short jump_if_right
lea
edx, [ebp+var_98]
lea
ecx, [ebp+var_28]
mov
[ebp+var_90], offset aWrong ; "wrong"
mov
[ebp+var_98], 8
call
ds:__vbaVarDup
lea
edx, [ebp+var_58]
lea
eax, [ebp+var_48]
push
edx
lea
ecx, [ebp+var_38]
push
eax
push
ecx
lea
edx, [ebp+var_28]
push
0
push
edx
call
ds:rtcMsgBox
lea
eax, [ebp+var_58]
lea
ecx, [ebp+var_48]
push
eax
lea
edx, [ebp+var_38]
push
ecx
lea
eax, [ebp+var_28]
push
edx
push
eax
jmp
short free_up_resources
; --------------------------------------------------------------------------jump_if_right:
lea
lea
mov
mov
call
lea
lea
push
lea
push
push
lea
push
edx, [ebp+var_98]
ecx, [ebp+var_28]
[ebp+var_90], offset aRight ; "Right"
[ebp+var_98], 8
ds:__vbaVarDup
ecx, [ebp+var_58]
edx, [ebp+var_48]
ecx
eax, [ebp+var_38]
edx
eax
ecx, [ebp+var_28]
0
push
call
lea
lea
push
lea
push
lea
push
push
ecx
ds:rtcMsgBox
edx, [ebp+var_58]
eax, [ebp+var_48]
edx
ecx, [ebp+var_38]
eax
edx, [ebp+var_28]
ecx
edx
free_up_resources:
push
4
call
ds:__vbaFreeVarList
add
esp, 14h
mov
[ebp+var_4], 0
push
offset call_emulate
jmp
short jump_as_a_call
; --------------------------------------------------------------------------lea
ecx, [ebp+var_18]
call
ds:__vbaFreeStr
lea
eax, [ebp+var_88]
lea
ecx, [ebp+var_78]
push
eax
lea
edx, [ebp+var_68]
push
ecx
lea
eax, [ebp+var_58]
push
edx
lea
ecx, [ebp+var_48]
push
eax
lea
edx, [ebp+var_38]
push
ecx
lea
eax, [ebp+var_28]
push
edx
push
eax
push
7
call
ds:__vbaFreeVarList
add
esp, 20h
retn
; --------------------------------------------------------------------------jump_as_a_call:
retn
; --------------------------------------------------------------------------call_emulate:
mov
push
mov
call
mov
mov
pop
pop
mov
pop
mov
pop
retn
Form_Load
eax, [ebp+arg_0]
eax
ecx, [eax]
dword ptr [ecx+8] ; Zombie_Release()
eax, [ebp+var_4]
ecx, [ebp+var_14]
edi
esi
large fs:0, ecx
ebx
esp, ebp
ebp
4
endp
edi
ebx
[ebp+arg_8]
[ebp+arg_C]
eax
ecx
edx
;
;
;
;
;
;
;
Context Pushed
HelpFile Pushed
ypos Pushed
xpos Pushed
Default pushed
Title Pushed
Prompt pushed
call
sub_7349DC68
; Function that causes Inputbox
; At this point EAX contains the entered string
push
mov
call
push
call
push
call
push
call
mov
pop
pop
pop
leave
retn
[ebp+arg_4]
; BSTR
edi, eax
esi ; __imp_SysFreeString
[ebp+arg_0]
; BSTR
esi ; __imp_SysFreeString
[ebp+var_4]
; BSTR
esi ; __imp_SysFreeString
[ebp+var_1C]
; BSTR
esi ; __imp_SysFreeString
eax, edi
; Sets EAX to the Return Value
edi
esi
ebx
; Close Stack Frame
1Ch
; Returns from here
In the first portion of the code, the push instructions push all the seven
parameters to the function that creates the InputBox Dialogbox. I know that with
the current example that I'm disassembling, it's not quite possible to believe
that all the push instructions stand for what I've mentioned. So what you can do
is disassemble the following code given below and set a breakpoint on the PUSH
instructions in the MSVBM60.DLL File using OllyDebug or SoftIce.
str1 = InputBox("This is prompt","This is Title","Default-Val",10,20, _
"c:\help.hlp",1)
With this you can actually verify the contents of the push instruction to
confirm what I've written.
Now, after the call instruction you can see a PUSH instruction pushing the
contents of a variable. This is a parameter for the SysFreeString Function.
Next is a MOV instruction transferring the contents of the EAX register into EDI.
EAX at this point of time contains the address of the String that we filled in
the Text Box. This is done to save the value of EAX.
Then the SysFreeString Function is called. This function takes 1 argument which
is the string that needs to be deallocated. This function does not return any
value after execution.
Did you notice something stupid?
If the SysFreeString Function does not return any value, then why were the
contents of EAX saved in EDI? And why is there a need to have a MOV EAX , EDI
instruction?
What a waste of precious bytes.
This is deploring code generated by Visual C++ 6.0 Compiler (which was used to
write the MSVBM60.DLL File) and since Visual BASIC programs use this routine, it
results in slow, sluggish programs.
And this is just one function...imagine what would happen if we analyzed all of
them?
Anyway, the original contents of the registers are restored, the stack frame is
closed (with LEAVE) and the function returns after adding 0x1C bytes to ESP.
Now let's have a look at this code portion.
call
mov
lea
call
push
call
mov
lea
neg
sbb
neg
neg
call
ds:rtcInputBox
edx, eax
ecx, [ebp+var_18]
ds:__vbaStrMove
eax
ds:__vbaStrCmp
esi, eax
ecx, [ebp+var_18]
esi
esi, esi
esi
esi
ds:__vbaFreeStr
After the call of rtcInputBox, EAX contains the entered string in the Text Box
of the InputBox dialog. The address of this string is moved to EDX.
Is this done to save the contents of the String for the compare function?
As obvious as it may seem, it is really not like that. Let us see.
The __vbaStrMove function moves a String from one place in memory to another
place. On Analysis of the function code it is found that this function accepts
two arguments and returns one value as shown below:
PARAMETERS:
EDX : Source String
ECX : Destination
RETURNS : Source String. Sets EAX to EDI (which holds value of EDX)
Now we see that by setting the value of EAX to EDX, we are setting the entered
string as a SOURCE string to be copied into another location. This is neat.
Now the Source String is pushed again and the __vbaStrCmp Function is called.
This on first glance looks wierd again. It seems that the StrCmp Function
accepts only one argument. Then what does it compare it with?
If you scroll above you will find a push instruction that pushes the address of
the string "Sanchit" ( push
offset aSanchit ; "Sanchit" )
Such cases remind us that unlike code generated by Pascal and C/C++ compilers,
Visual BASIC functions can have it's arguments pushed anywhere and not right
before the function call.
Keep this thing in mind when you set out to disassemble your own Visual BASIC
programs.
Now after the Comparing function returns its value via the EAX register, it is
copied to ESI.
Then the LEA instruction is used to load the address of a variable in the ECX
register. Now since we are aware of VB's tricks we know that this is a parameter
to the __vbaFreeStr function. You should notice that the same variable which
held the value of the entered string is now being passed to this function to
deallocate it as its not required after the comparison has been done.
Now let's talk about this code fragment:
neg
sbb
neg
neg
call
esi
esi, esi
esi
esi
ds:__vbaFreeStr
The NEG statement's actual use is to change the sign of a number for example,
from 3 to -3.
But this one has an indirect use. This Instruction affects many flags. But the
one it is meant for is the Carry Flag (CF) which is used in the next SBB
Instruction.If ESI is equal to 0 then CF is reset to 0 and otherwise is set to 1.
Now the SBB Instruction stands for
be translated to this:
ESI = ESI - (ESI + CF);
IX.
CONCLUSION [END1]
This isn't exactly the end of the tutorial. I'd rather say that it is the end
for now. This topic is vast and I'm trying to include explanation and analysis
of all Visual BASIC functions. If I plan to release this tutorial with all
functions inclusive, it's going to take a lot of time.
So i've decided to post this tutorial first and keep updating it every 15 to 20
days. You can check the LAST UPDATED Section in the beginning of the Tutorial to
see how recently this tutorial has been updated.
Keep checking for updated versions every month.
I hope you've enjoyed my tutorial as I've put in a lot of hard work and time on
writing this.
Since I haven't come across any Books or Articles on this subject, I don't quite
know what exactly is expected from my tutorial. I would appreciate it if you
could email me suggestions and comments on this tutorial.
I may not be able to reply to every email, but I do read each one of them.
Thanks.
X.
XI.
REFERENCES [REFR]