After 3 days off with concussion I decided to break my brain in gently by improving my hexdump utility. The result is - rufff! - but functional and may help you if you want to follow 32-bit addresses at run time. It lets you click on an address, check that the memory thus referenced is readable, and a double-click moves the hexdump window to the address identified. There is a back button. I'm posting it here in anticipation of improvements (hopefully by someone else), one day it may be clean enough for the Source Code Forum.
Just #include the code below and call it like hexdump address, count.
This could develop in various ways, if you are interested please post changes or let me know your ideas.
Thanks.
Just #include the code below and call it like hexdump address, count.
This could develop in various ways, if you are interested please post changes or let me know your ideas.
Thanks.
Code:
' ' hexdump.inc ' dump data to screen in hex and character ' in 256-byte chuncks ' starting at a given address, or via a register (ESP or EBX, add more as required) ' ' Chris Holbrook 6 Jul 2008 ' 'dsply first 256 from a memory address as a block of hex digits with a character map on the right ' param 1 is byte ptr to memory to view, ' param 2 is max number of bytes to view ' param 3 is a register name. If param 1 is zero then ' the register will be used to point to the data to be dumped to the screen. ' example of calling: 1) hexdump (byval varptr(x), 1024) 2) hexdump ( 0, 256, "ESP") ' return handle to dialog ' ' changes 5-sep-2008 ' a left mouse click in the hexdump area will highlight the 32-bit address at the ' click location and display it "right way round", in pink if there is no readable ' memory there and in green if there is. double-click the highlighted address ' to move the hexdump window to that address. ' Added BACK button to return from above excursion to the previous page '--------------------------------------------------------------------------- %idc_base_lab = 1004 %idc_ofs_lab = 1005 %idc_cur_lab = 1006 %idc_data_lab = 1001 %idc_prev_bn = 1002 %idc_next_bn = 1003 %idc_box_lab = 1007 %idc_back_bn = 1008 GLOBAL gstack() AS LONG GLOBAL gstackptr AS LONG '---------------------------------------------------------------------------------- FUNCTION MakeFont(BYVAL fName AS STRING, BYVAL ptSize AS LONG, _ OPT BYVAL attr AS STRING) AS DWORD '-------------------------------------------------------------------- ' Create a desired font and return its handle. ' attr = "biu" for bold, italic, and underlined (any order) '-------------------------------------------------------------------- LOCAL hDC AS DWORD, CharSet AS LONG, CyPixels AS LONG LOCAL BOLD, italic, uLine AS LONG IF LEN(attr) THEN IF INSTR(LCASE$(attr), "b") THEN BOLD = %FW_BOLD IF INSTR(LCASE$(attr), "i") THEN italic = 1 IF INSTR(LCASE$(attr), "u") THEN uLine = 1 END IF hDC = GetDC(%HWND_DESKTOP) CyPixels = GetDeviceCaps(hDC, %LOGPIXELSY) ReleaseDC %HWND_DESKTOP, hDC PtSize = 0 - (ptSize * CyPixels) \ 72 FUNCTION = CreateFont(ptSize, 0, 0, 0, BOLD, italic, uLine, _ %FALSE, CharSet, %OUT_TT_PRECIS, _ %CLIP_DEFAULT_PRECIS, %DEFAULT_QUALITY, _ %FF_DONTCARE , BYCOPY fName) END FUNCTION '--------------------------------------------------------------------------- SUB pop ( BYREF l AS LONG) l = gstack(gstackptr) DECR gstackptr END SUB '--------------------------------------------------------------------------- SUB push ( l AS LONG) INCR gstackptr gstack(gstackptr) = l END SUB '--------------------------------------------------------------------------- CALLBACK FUNCTION hexdumpCB AS LONG LOCAL s AS STRING LOCAL COUNT, i, j, l AS LONG STATIC ppage, pbase, q AS BYTE PTR STATIC startofchunk, maxlength AS LONG LOCAL X, Y AS LONG LOCAL row, col AS LONG LOCAL hfont AS DWORD LOCAL pt AS pointapi STATIC trget AS LONG STATIC lMaxReadableMem, lcolor AS LONG SELECT CASE CBMSG CASE %WM_INITDIALOG DIALOG GET USER CBHNDL, 0 TO pbase ppage = pbase DIALOG GET USER CBHNDL, 1 TO maxlength GOSUB dsply CONTROL DISABLE CBHNDL, %IDC_BACK_BN ' CASE %WM_COMMAND SELECT CASE CBCTL CASE %idc_prev_bn ' prev ppage = ppage - 256 GOSUB dsply CASE 1003 ' next ppage = ppage + 256 GOSUB dsply CASE %IDC_BOX_LAB IF CBCTLMSG = %STN_DBLCLK THEN IF (lmaxreadablemem > 0 ) AND iswindow ( getdlgitem(CBHNDL, %IDC_BOX_LAB) )THEN push pbase push ppage push maxlength CONTROL ENABLE CBHNDL, %IDC_BACK_BN ppage = trget pbase = trget maxlength = lmaxreadablemem deleteobject hfont CONTROL KILL CBHNDL, %IDC_BOX_LAB GOSUB dsply END IF END IF CASE %IDC_BACK_BN IF CBCTLMSG = %BN_CLICKED THEN pop maxlength pop ppage pop pbase IF gstackptr = 0 THEN CONTROL DISABLE CBHNDL, %IDC_BACK_BN GOSUB dsply END IF END SELECT ' CASE %WM_LBUTTONDOWN pt.X = LO(WORD,CBLPARAM): pt.Y = HI(WORD,CBLPARAM) IF getdlgitem(CBHNDL, %IDC_BOX_LAB) <> 0 THEN deleteobject hfont CONTROL KILL CBHNDL, %IDC_BOX_LAB END IF IF childwindowfrompoint(CBHNDL, pt.x, pt.y) = getdlgitem(CBHNDL, %IDC_BOX_LAB) THEN EXIT SELECT DIALOG PIXELS CBHNDL, pt.x, pt.y TO UNITS X, Y row = (Y - 40)\10: col = (x -17)\16 ': ? str$(row) + str$(col) IF (row < 0) OR (row > 15) THEN EXIT SELECT IF (col < 0) OR (col > 15) THEN EXIT SELECT CONTROL ADD LABEL, CBHNDL, %IDC_BOX_LAB, "", X-2, Y-2, 64, 12, %SS_SUNKEN OR %SS_NOTIFY, %WS_EX_TOPMOST hfont = makefont ( "Courier New", 10) CONTROL SEND CBHNDL, %IDC_BOX_LAB, %WM_SETFONT, hFont, 0 ' invert the number in the current + suceeding 3 byte s = ""' " trget = 0 FOR i = 3 TO 0 STEP -1 q = ppage + (row*16) + col + i s = s + HEX$(@q,2) + " " NEXT trget = VAL ( "&H" + REMOVE$(s,ANY $SPC)) FOR i = 0 TO 5 IF isbadreadptr(trget,4^i) THEN IF i = 0 THEN lMaxReadableMem = 0 lcolor = %RED END IF ELSE lMaxReadableMem = 4^i lcolor = %GREEN END IF NEXT CONTROL SET COLOR CBHNDL, %IDC_BOX_LAB, 0, lcolor CONTROL SET TEXT CBHNDL, %IDC_BOX_LAB, s 'remove$(s, $SPC) DIALOG REDRAW CBHNDL 'sleep 500 END SELECT EXIT FUNCTION dsply: s = STRING$(80 * 16, $SPC) FOR i = 0 TO 15 FOR j = 0 TO 15 'IF (i * 16) + j + startofchunk > maxlength THEN ITERATE q = ppage + (i*16) + j MID$(s, (i * 80) + (j*3)+3, 2) = HEX$(@q,2) IF INSTR ( "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"" £$%^&*()_+{}[]:@~;'#,./<>?`¬",CHR$(@q)) <> 0 THEN MID$(s, (i * 80) + 52 + j, 1) = CHR$(@q) ELSE MID$(s, (i * 80) + 52 + j, 1) = "." END IF NEXT MID$(s, ((i) * 80)+1, 1) = HEX$(i) MID$(s, ((i+1) * 80) - 2, 2) = $CRLF NEXT s = " 0 1 2 3 4 5 6 7 8 9 A B C D E F" + _ $CRLF + STRING$(51,"-") + " " + STRING$(16,"-") + $CRLF + " " + s CONTROL SET TEXT CBHNDL, %idc_data_lab, s IF ppage <= pbase THEN CONTROL DISABLE CBHNDL, %idc_prev_bn ELSE CONTROL ENABLE CBHNDL, %idc_prev_bn END IF IF ppage + 256 >= pbase + maxlength THEN CONTROL DISABLE CBHNDL, 1003 ELSE CONTROL ENABLE CBHNDL, 1003 END IF CONTROL SET TEXT CBHNDL, %idc_base_lab, "BASE ADDRESS: " + HEX$(pbase) + "(" + STR$(pbase) + ")" CONTROL SET TEXT CBHNDL, %idc_ofs_lab, "MAX BYTES: " + HEX$(maxlength) + "(" + STR$(maxlength) + ")" CONTROL SET TEXT CBHNDL, %idc_cur_lab, "PAGE OFFSET: " + HEX$(ppage - pbase) + "(" + STR$(ppage- pbase) + ")" RETURN END FUNCTION '------------------------------------------------------------------------------- FUNCTION hexdump ( BYVAL pb AS BYTE PTR, n AS LONG, OPT reg AS STRING) AS DWORD LOCAL hdlg AS DWORD LOCAL hfont AS LONG DIM gstack (0 TO 100) AS GLOBAL LONG DIALOG NEW 0, "hex memory dump", 0, 0, 390, 245, %WS_POPUP OR %WS_BORDER OR _ %WS_DLGFRAME OR %WS_SYSMENU OR %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME OR %DS_3DLOOK OR %DS_NOFAILCREATE OR _ %DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg CONTROL ADD LABEL, hdlg, %idc_data_lab, "",0, 20, 390, 195, %WS_CHILD OR %WS_VISIBLE OR %SS_NOWORDWRAP CONTROL ADD LABEL, hdlg, %idc_base_lab, "Base:",5,5, 130, 15, %WS_CHILD OR %WS_VISIBLE OR %SS_NOWORDWRAP CONTROL ADD LABEL, hdlg, %idc_ofs_lab, "Max Length:",145,5, 100,15, %WS_CHILD OR %WS_VISIBLE OR %SS_NOWORDWRAP CONTROL ADD LABEL, hdlg, %idc_cur_lab, "Curent ofs:",255,5, 100,15, %WS_CHILD OR %WS_VISIBLE OR %SS_NOWORDWRAP CONTROL ADD BUTTON, hdlg, %idc_prev_bn, "<", 5, 225, 10, 15, _ %WS_CHILD OR %WS_VISIBLE OR %BS_PUSHBUTTON OR %BS_TEXT OR %BS_CENTER OR %BS_VCENTER CONTROL ADD BUTTON, hdlg, %idc_next_bn, ">", 25, 225, 10, 15, _ %WS_CHILD OR %WS_VISIBLE OR %BS_PUSHBUTTON OR %BS_TEXT OR %BS_CENTER OR %BS_VCENTER CONTROL ADD BUTTON, hdlg, %idc_back_bn, "BACK", 45, 225, 30, 15, _ %WS_CHILD OR %WS_VISIBLE OR %BS_PUSHBUTTON OR %BS_TEXT OR %BS_CENTER OR %BS_VCENTER IF pb = 0 THEN SELECT CASE reg CASE "EBX" !mov pb, ebx CASE "ESP" !mov pb, esp END SELECT END IF DIALOG SET USER hdlg, 0, pb DIALOG SET USER hdlg, 1, n hfont = makefont ( "Courier New", 10) CONTROL SEND hDlg, 1001, %WM_SETFONT, hFont, 0 DIALOG SHOW MODAL hdlg CALL hexdumpCB DeleteObject hFont END FUNCTION
Comment