Last active
October 11, 2016 05:14
-
-
Save toptensoftware/31e26b7327e461a151c8f359e3bfe210 to your computer and use it in GitHub Desktop.
Fake demonstration of calling Windows API from 16-bit code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class FakeUserDll : ModuleBase | |
{ | |
public FakeUserDll() | |
{ | |
} | |
// A reference back to the machine | |
Machine _machine; | |
// Address of the 16-bit MessageBox thunk | |
uint _addressMessageBoxThunk; | |
// Called by module manager when module loaded | |
public override void Init(Machine machine) | |
{ | |
// Save the machine reference | |
_machine = machine; | |
// Create a thunk in the 16-bit world that will call our C# MessageBox() function | |
_addressMessageBoxThunk = machine.CreateSystemThunk(MessageBox, 12, false); | |
} | |
// The ordinal number of the MessageBox function as exported from the user.dll | |
const ushort ORD_MESSAGEBOX = 0x0001; | |
// Called by Module16 when linking | |
public override uint GetProcAddress(ushort ordinal) | |
{ | |
// Is caller asking for the MessageBox function? | |
if (ordinal == ORD_MESSAGEBOX) | |
return _addressMessageBoxThunk; | |
// Unknown function | |
return 0; | |
} | |
// Import the real MessageBox function from the real Windows (P/Invoke) | |
[DllImport("user32.dll", CharSet = CharSet.Auto)] | |
public static extern int MessageBox(IntPtr hWnd, string message, string title, int options); | |
// Handler for the thunk created in Init. | |
// ie: when 16-bit code calls the MessageBox thunk, execution will land here | |
void MessageBox() | |
{ | |
// Parameters to 16-bit MessageBox are: | |
// HWND hWnd - 2 byte parent window handle | |
// LPCSTR pszMessage - 4 byte far string pointer to message | |
// LPCSTR pszTitle - 4 byte far string pointer to title | |
// int flags - 2 byte integer flags | |
// Read parameters from the VM stack | |
ushort hWnd = _machine.ReadWord(_machine.ss, (ushort)(_machine.ss + 4)); | |
uint pszMessage = _machine.ReadDWord(_machine.ss, (ushort)(_machine.ss + 6)); | |
uint pszTitle = _machine.ReadDWord(_machine.ss, (ushort)(_machine.ss + 10)); | |
ushort flags = _machine.ReadWord(_machine.ss, (ushort)(_machine.ss + 14)); | |
// Only null parent windows are supported atm | |
if (hWnd != 0) | |
throw new VirtualException("No window handle mapping yet"); | |
// Read the strings from the VM memory | |
string strMessage = _machine.ReadString(pszMessage); | |
string strTitle = _machine.ReadString(pszTitle); | |
// Call the real deal | |
int retv = MessageBox(IntPtr.Zero, strMessage, strTitle, (int)flags); | |
// Setup the return value | |
_machine.ax = (ushort)(short)retv; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment