Main Menu
Main Page
Recent changes
Random page


Major Glitches
Trainer escape glitch
Old man trick
Celebi Egg trick
Select glitches (Japan)
SRAM glitch
CoolTrainer♀ corruption
LOL glitch
Rival LOL glitch
Super Glitch
ZZAZZ glitch
Pomeg data corruption glitch (Glitzer Popping)
Elite Four door glitch (Japan)
Pokémon merge glitch
Pokémon cloning
Time Capsule exploit
Arbitrary code execution
Coin Case glitches

Other Glitch Categories
Glitches by generation
Glitches between two generations
Japan-only/language specific glitches
Music glitches
Natural glitches
Non-core series glitches
Non-Pokémon glitches
Officially acknowledged glitches
Recurring glitches
Dead glitches

Pokémon GameShark codes
The Big HEX List
Glitch Pokémon cries
GB programming
Debugging features
Easter eggs
Error traps
Glitch areas
Glitch myths
Non-glitch exploits
Placeholder texts
Pokémon glitch terminology
Unused content and prerelease information

Useful Tools
8F Helper
GBz80 to Items
Old man trick name generator
PATH (Prama's Advanced Tweaking Heaven)
Save file editors
Special stat/Pokémon converter
Trainer escape Trainer Pokémon finder

Legendary Star Blob 2 (Hakuda)
Pokémon Speedruns wiki
PRAMA Initiative
Become an affiliate!

Site Source Code

Search Wiki


Search Forums


Author Topic: Executing assembly language code in Visual Basic  (Read 2384 times)

0 Members and 1 Guest are viewing this topic.


  • Loose cannon mod who lives on the edge and doesn't play by the rules
  • Staff
  • *****
  • Offline Offline
  • Gender: Female
  • Cool story m8
    • View Profile
    • Github and whatnot
Executing assembly language code in Visual Basic
« on: June 10, 2013, 12:08:58 pm »
(Sure is a lot of Basic-related language threads around here... oh well.)

This isn't a help topic or anything like that, but I figured this is so brilliant and at the same time so completely and utterly stupid that I should post it here to see if anyone else is as crazy as I am.
But it's not all my fault, I took the idea from here:

I took it upon myself to rearrange the code to something I consider a bit less ugly (I'm not sure that other one actually works).

Code: [Select]
  MultiUse = -1  'True
Attribute VB_Name = "AssemblyHax"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit

#If VBA7 = 0 Then
    Private Enum LongPtr
         NULL_PTR = 0
    End Enum
    Private Const NULL_PTR as LongPtr = 0
#End If

Private Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) As LongPtr
Private Declare Function GlobalLock Lib "kernel32" (ByVal hMem As LongPtr) As LongPtr
Private Declare Function GlobalFree Lib "kernel32" (ByVal hMem As LongPtr) As LongPtr
Private Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As LongPtr) As BOOL

Private Declare Sub GetMem4 Lib "msvbvm60" (ByVal addr as LongPtr, ByRef out as Long)
Private Declare Sub RtlMoveMemory Lib "kernel32" (dest As Any, src As Any, ByVal length As Long)

Private hMem As LongPtr

Private Function decodeBytes(s As String) As Byte()
    Dim out() As Byte, i As Long
    Dim size As Long
    size = Len(s) \ 2
    ReDim Preserve out(0 To size - 1)
    For i = 1 To size
        out(i - 1) = CByte("&H" & Mid$(s, i * 2 - 1, 2))
    decodeBytes = out
End Function

Private Function getLong(addr as LongPtr) as Long
GetMem4 addr, getLong
End Function

Function dontCallThisFunction(ByRef buf As Byte) As Long
End Function

Function executeASM(ByVal asm As String) As String
    Dim b() As Byte
    b = decodeBytes(asm)
    Dim vTablePtr As LongPtr
    vTablePtr = getLong(ObjPtr(Me))
    Dim memPtr As Long
    hMem = GlobalAlloc(0, Len(asm) \ 2)
    memPtr = GlobalLock(hMem)
    RtlMoveMemory ByVal memPtr, b(0), Len(asm) \ 2
    GlobalUnlock hMem
    RtlMoveMemory ByVal vTablePtr + &H1C, memPtr, 4
    Dim buf(0 To 11) As Byte
    dontCallThisFunction buf(0)
    executeASM = StrConv(buf, vbUnicode)
End Function

Private Sub Class_Terminate()
    If hMem <> NULL_PTR Then GlobalFree hMem
End Sub

Function cpuID() As String
    cpuID = executeASM("578B7C240C33C00FA2891F895704894F085F33C0C3")
End Function

So you basically just create a new instance of AssemblyHax after importing this class, and call its cpuID method. The rest is magic.

Oh, alright. I'll attempt to explain said magic, and why this needs to be a class and not a standard module:
- COM objects (which all VB objects are) use virtual method tables internally
- executeASM first gets this object's actual memory address and dereferences the Long variable there to get the pointer to this v-table
- It then overrides the first function pointer of this v-table (hence it is important that dontCallThisFunction is the very first public function in order of declaration) with some arbitrary byte values, which is stored as a String because it's just easier that way
- Executes dontCallThisFunction which now actually has a method body (with those bytes), passing it a Byte array so it can store the returned values in some registers or however x86 assembly works
- Returns a string saying "GenuineIntel" or whatever

Feel free to throw up after reading this. I don't really blame you.

EDIT: Whoops, I forgot something I had in another module (namely the LongPtr hack) that this was taken from. Won't compile without it, so I put it in the private declarations. And the byteArray function wasn't even used. My stupid.
« Last Edit: June 10, 2013, 10:22:58 pm by Zowayix »

I need a new siggy, because this siggy is shitty... shittiggy... shiggy.... something.


  • French Fry Overlord
  • GCLF Member
  • *
  • Offline Offline
  • Gender: Male
    • View Profile
Re: Executing assembly language code in Visual Basic
« Reply #1 on: June 10, 2013, 03:30:34 pm »
T.T I haven't used basic since highschool....well wait freshman year in college with the TI 84, but that was just 3 to 4 lines of script...
:( i've forgotten so much...