|
Not much of a demo here, just a really useful module you can add to your projects when you need to pick apart memory your process is using. The core function, HexDump(lpBuffer, Length), provides a common "hex editor view" of that location in memory by printing it out directly to the Immediate window. For example, if an API returns a pointer to a structure, and you want to see exactly what's within that structure as you try to decode the SDK docs from C to VB, passing that pointer to HexDump would give you something like this:
================================================================================= lpBuffer = &h1AC998 nBytes = 256 001AC998 0000 C8 C9 1A 00 F0 C9 1A 00-02 00 00 00 23 BD CA 99 ............#... 001AC9A8 0010 DC 1D D3 11 BD 80 00 10-4B 7A 56 08 08 CA 1A 00 ........KzV..... 001AC9B8 0020 18 CA 1A 00 7D 01 00 E0-28 CA 1A 00 00 00 00 00 ....}...(....... 001AC9C8 0030 5C 00 5C 00 4E 00 54 00-35 00 30 00 2D 00 53 00 \.\.N.T.5.0.-.S. 001AC9D8 0040 56 00 52 00 2E 00 6C 00-6A 00 2E 00 68 00 6F 00 V.R...l.j...h.o. 001AC9E8 0050 6D 00 65 00 00 00 00 00-5C 00 5C 00 4E 00 54 00 m.e.....\.\.N.T. 001AC9F8 0060 35 00 30 00 2D 00 53 00-56 00 52 00 00 00 44 00 5.0.-.S.V.R...D. 001ACA08 0070 6C 00 6A 00 2E 00 68 00-6F 00 6D 00 65 00 00 00 l.j...h.o.m.e... 001ACA18 0080 6C 00 6A 00 2E 00 68 00-6F 00 6D 00 65 00 00 00 l.j...h.o.m.e... 001ACA28 0090 44 00 65 00 66 00 61 00-75 00 6C 00 74 00 2D 00 D.e.f.a.u.l.t.-. 001ACA38 00A0 46 00 69 00 72 00 73 00-74 00 2D 00 53 00 69 00 F.i.r.s.t.-.S.i. 001ACA48 00B0 74 00 65 00 2D 00 4E 00-61 00 6D 00 65 00 00 00 t.e.-.N.a.m.e... 001ACA58 00C0 4C 4D 45 4D 98 C9 1A 00-00 00 00 00 00 00 00 00 LMEM............ 001ACA68 00D0 0C 00 1B 00 00 01 08 00-02 00 00 00 03 00 00 00 ................ 001ACA78 00E0 00 00 00 00 00 00 00 00-03 00 00 00 D0 D0 1A 00 ................ 001ACA88 00F0 B0 4D 1A 00 D0 35 B3 77-15 7E 00 00 59 1F 1D 27 .M...5.w.~..Y..' =================================================================================Also included in this module are three functions that can be used to dereference string (both Unicode and ANSI) and DWORD pointers to normal VB variables:
Public Function PointerToStringA(ByVal lpStringA As Long) As String Dim Buffer() As Byte Dim nLen As Long If lpStringA Then nLen = lstrlenA(ByVal lpStringA) If nLen Then ReDim Buffer(0 To (nLen - 1)) As Byte CopyMemory Buffer(0), ByVal lpStringA, nLen PointerToStringA = StrConv(Buffer, vbUnicode) End If End If End Function Public Function PointerToStringW(ByVal lpStringW As Long) As String Dim Buffer() As Byte Dim nLen As Long If lpStringW Then nLen = lstrlenW(lpStringW) * 2 If nLen Then ReDim Buffer(0 To (nLen - 1)) As Byte CopyMemory Buffer(0), ByVal lpStringW, nLen PointerToStringW = Buffer End If End If End Function Public Function PointerToDWord(ByVal lpDWord As Long) As Long Dim nRet As Long If lpDWord Then CopyMemory nRet, ByVal lpDWord, 4 PointerToDWord = nRet End If End FunctionHardly a project goes by when I don't find the need for one or more of those. A great many SDK structures are made up of a series of pointers, followed by a buffer of regions that are pointed to. This combo will help you decode any odd results you encounter.
This sample, or the one from which it originally derived, was published (or at least peripherally mentioned) in the following article(s):
- Look Into Raw Memory Contents, Ask the VB Pro, VBPJ, February 2001
- Let Me Count the Ways, Desktop Developer, VSM, November 2001
- Customizing the Ride (Part 1), Classic VB Corner, VSM Online, April 2010
This sample uses the following API calls:
Module Library Function MHexDump.bas kernel32 lstrlen
lstrlen
RtlMoveMemoryDon't see what you're looking for? Here's a complete API cross-reference.
Please, enjoy and learn from this sample. Include its code within your own projects, if you wish. But, in order to insure only the most recent code is available to all, I ask that you don't share the sample by any form of mass distribution. Download HexDump.zip, 3Kb, Last Updated: Wednesday, December 6, 2000