VB5 Serial Number Tip

Welcome to a slightly modified page. I'm going to describe a few small tips with regards to Visual Basic applications (specifically those with serial number protections). The first thing to know about VB is that the program executable files are essentially just scripts running functions exported from the VB run-time dll. You'll notice that VB exe's tend to be fairly small although this isn't always true. You'll immediately recognise a VB program when you disassemble it because of the dll imports or when you land in these dll's via SoftICE.

vbrun300.dll - VB3 (16-bit)
vb40016.dll - VB4 (16-bit) - rare.
vb40032.dll - VB4 (32-bit)
msvbvm50.dll - VB5 (32-bit)

The VB dll essentially acts as a substitute API for the Win32 API, although most VB applications still use the Win32 subsystem. You should add all of the VB dll's as exports in your winice.dat file if you wish to set breakpoints on VB functions.

In most VB applications, we can try >bpx Hmemcpy but you'll find yourself stepping through msvbvm50.dll and very quickly lost in the mire that is VB. In most cases you'll never actually reach the real compare routine inside the exe, you'll usually have to rely on the lazy string approach. Remember also that VB programs store and compare strings in wide character format (essentially string padding with 20h).

Ordinary String Example: CRACKZ (43h 52h 41h 43h 4Bh 5Ah).
Wide Character Format: C R A C K Z (43h 20h 52h 20h 41h 20h 43h 20h 4Bh 20h 5Ah).

I'll introduce 1 useful VB breakpoint, that is MultiByteToWideChar, in most VB reversing finding the right breakpoint is usually the difficulty. Setting MBTWC inside SoftICE and attempting to register should get you returned inside msvbvm50.dll on most occasions, now look for registers (EAX & EBX) holding the length of the string you entered. If you don't see it, try hitting Ctrl+D again. You may get another return (repeat ad infinitum).

Once you've got the string length in a register you should step a few lines and then do a search, with any luck you'll find the string you entered either lying around in a register or very close to one. If you scroll the data window around your input you will probably be able to find your good code sat lazily in memory.


Well, here is an addition by myself as I was so irritated with the lack of VB5 reversing approaches. I bring you now 'exclusively' (if thats the word) the VB5 String Compare routine, merely a simple but slightly different variation on the VB4 & VB3 compare code.

:0F00D9EA PUSH ESI (56)
:0F00D9EB PUSH EDI (57)
:0F00D9EC MOV EDI,[ESP+10] (8B7C2410)
:0F00D9F0 MOV ESI,[ESP+0C] (8B74240C)
:0F00D9F4 MOV ECX,[ESP+14] (8B4C2414)
:0F00D9F8 XOR EAX,EAX (33C0)
:0F00D9FA REPZ CMPSW (F366A7) <-- Compare those strings.
:0F00D9FD JZ 0F00DA04 (7405)

If you are in any doubt as to what you should do now, go and read my tutorial about INT 3 patching, just patch a copy of msvbvm50.dll and use >bpint 3 to break in on this compare code, and if its being used you've beaten your target. This technique will not work all of the time but its certainly worth keeping a patched copy of the dll on your system for other VB5 programs.

Return to Visual Basic

© 1998,1999, 2000 CrackZ. 26th May 1998.