Author: David Zimmer
Date: 08.25.19 - 8:37am

Next lets look at a pcode that accepts a variable number of arguments. Lets start with my favorite pick up line.
Print #f, "hi", "you" 
401881    FF0E 08001000         PrintFile

Print #f, "hi", "you", "smell"
401898    FF0E 09001400         PrintFile

Print #f, "hi", "you", "smell", "good"
4018B3    FF0E 0A001800         PrintFile

Print #f, "hi", 1, myCurrency, myDouble
401868    FF0E 07002000         PrintFile
With these variations we can see the arg bytes changing. If we assume two words, the last argument is growing 4 bytes every time we add a string to the call. So that is our stack cleanup or stack check variable as seen in the previous instruction. The last call with a Currency and Double gives more confirmation each with size 8.

The first word is incrementing by one each time we add an arg, and its not the arg count. Every string we add to a function will have an entry in the const pool. You can leave the print call the same, and add a string constant above it and see if that first word changes. If it does, then its a pool index. That does happen in this case, so lets take a look at the pool entries using the const pool viewer form.

Each pool entry is an address that contains the following embedded data: (in same order as above)
02 00 08 88 00
03 00 08 08 88 00
04 00 08 08 08 88 00
See the pattern? 08 is VT_BSTR. Let me break the last one down for you: (note: 04 00 is the little endian 2 byte word 0004 and the runtime actually does an AND 0x3f on all the value, (and havent bothered to look at what the remaining high bits of the final byte represent yet))
Print #f, "hi", 1, myCurrency, myDouble
04 00 08 02 06 85 00 - 4 entries: BSTR, I2, VT_CY, VT_R8
There are other opcode which take a variable number of bytes. FFreeAd for example can free multiple strings all in one opcode. That one uses the following format:
464576    29  [12 bytes] FFreeAd var_98 var_150 var_154 
46457F    36  [24 bytes] FFreeVar var_AC var_CC var_EC var_10C var_12C var_14C 
46458E    00 03          ErrNext loc_464591

464576 29 06 00 68 FF B0 FE AC FE 36
46457F 36 0C 00 54 FF 34 FF 14 FF F4 FE D4 FE B4 FE 00 03 
This time the variable byte lengths are embedded right into the opcode byte stream itself and not in a referenced const pool entry. You can see the first opcode byte, then a 2 byte length in little endian format, then XX bytes representing the var_XX (all ebp- negative values starting with FF or FE) then at teh end I also included the first opcode of the next instruction that you can also see in the disassembly dump.

The reason i point out the different methods they use is so you can get insight into their heads and see the various techniques they were using when they designed their pcode implementation. The more we see the faster the reversing gets.

These two different opcode implementations were probably coded by different people or at different times. I would assume MS developers had their own pcode disassembler and probably even a pcode debugger too.

Using the const pool for variable bytes is a bit more complex, but also cleaner. Also in this case since they are doing AND operations on the embedded const pool data, the data is more complex. Both hint at it being a latter language feature. Freeing strings and variants would have been one of the first requirements. Updating PrintFile to accept more complex datatypes an extension.

Sometimes I wonder if anyone understands wtf I am talking about in these posts lol. I know its a very very small crowd who would understand and even a smaller subset of those who would care but it tickles my fancy so heeerree weeee arrreeeee.

I guess this is my CompSci 601 class in Virtual Machine Design.

Comments: (0)

Leave Comment:
Email: (not shown)
Message: (Required)
Math Question: 89 + 20 = ? followed by the letter: B 

About Me
More Blogs
Main Site
Posts: (year)
2024 (1)
     vbdec backstory
2023 (4)
     Yara Workbench Automation
     VS linker versions
     IDA decompiler comments
2022 (5)
     VB6 Implements
     VB6 Stubs BS
     VB6 TypeInfo
     VB6 VTable Layout
     Yara isPCode rule
2021 (2)
     VB6 Gosub
2020 (5)
     AutoIT versions
     IDA JScript 2
     Using VB6 Obj files from C
     Yara Corrupt Imports
     Yara Undefined values
2019 (6)
     Yara WorkBench
     vb6 API and call backs
     UConnect Disable Cell Modem
2017 (5)
     IDA python over IPC
     dns wildcard blocking
     64bit IDA Plugins
     anterior lines
     misc news/updates
2016 (4)
     KANAL Mod
     Decoders again
     CDO.Message Breakpoints
     SysAnalyzer Updates
2015 (5)
     SysAnalyzer and Site Updates
     crazy decoder
     ida js w/dbg
     flash patching #2
     JS Graphing
2014 (5)
     Delphi IDA Plugin
     scdbg IDA integration
     API Hash Database
     Winmerge plugin
     IDACompare Updates
2013 (9)
     Guest Post @ hexblog
     TCP Stream Reassembly
     SysAnalyzer Updates
     Apilogger Video
     Shellcode2Exe trainer
     scdbg updates
     IDA Javascript w/IDE
     Rop Analysis II
     scdbg vrs ROP
2012 (13)
     flash patching
     x64 Hooks
     micro hook
     jmp api+5 *2
     SysAnalyzer Updates
     InjDll runtime config
     C# Asm/Dsm Library
     Shellcode Hook Detection
     Updates II
     Java Hacking
     Windows 8
     Win7 x64
2011 (19)
     Graphing ideas
     .Net Hacking
     Old iDefense Releases
     hll shellcode
     ActionScript Tips
     -patch fu
     scdbg ordinal lookup
     scdbg -api mode
     Peb Module Lists
     scdbg vrs Process Injection
     GetProcAddress Scanner
     scdbg fopen mode
     scdbg findsc mode
     scdbg MemMonitor
     demo shellcodes
     scdbg download
     api hashs redux
     Api hash gen
2010 (11)
     Retro XSS Chat Codes
     Exe as DLL
     Olly Plugins
     Debugging Explorer
     Attach to hidden process
     JS Refactoring
     Asm and Shellcode in CSharp
     Fancy Return Address
     PDF Stream Dumper
     Malcode Call API by Hash
     WinDbg Cheat Sheet
2009 (1)
     GPG Automation