Solved

Simple Hex Dump (Example: 0000   00 49 50 51   .123)

Posted on 2004-09-16
10
367 Views
Last Modified: 2011-09-20
I'd like some source to a function that will display a hex dump of memory such as the following example....   2

0000  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0010  49 50 51 52 00 00 00 00 00 00 00 00 00 00 00 00  1234............
0020  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0030  00 00 00 00 00 00 00 00 00 00 00 00               ............

Basically something you would see in any normal hex dump program such as windows packet editor or something for example...  Would look better in monospaced fonts.

0
Comment
Question by:werehamster-
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 2
  • 2
10 Comments
 

Author Comment

by:werehamster-
ID: 12078905
Anyway, this is what I got so far...  It is just a bit buggy as it doesn't display the first line sometimes...

procedure HexDisplay(var Data; Len: Integer);
var
  x1, y1 : Integer;
  iLen, iPos : Integer;
  sB, sT, sOut, sOffset : String;
  Offset : Integer;
type
  TByteArray = array[0..64000] of Byte;
begin
  iLen := Len;
  If iLen = 0 then Exit;
  sB := '';
  sOut := '';
  Offset := 0;
  x1 := 0;
  y1 := 0;
  ipos := 0;

  for x1 := 1 to ((iLen-1) div 16)+1 do
    Begin
      sOffset := IntToHex(Offset,4);
      sT := '';
      sB := '';
      for y1 := 1 to 16 do
        Begin
          iPos := 16 * x1 + y1;
          if iPos > iLen then Break;
          sB := sB + ' ' + IntToHex(Byte(TByteArray(Data)[iPos]),2);
          Case Byte(TByteArray(Data)[iPos]) of
            0,9,10,13 : sT := sT + '.'
          Else
            sT := sT + Char(TByteArray(Data)[iPos]);
          End;
        End;
      while length(sB) < 8 do sB := sB + ' ';

      Form1.OutPutBox.Lines.Add(sOffset+': '+sB+' '+sT);
      Offset := Offset + 16;
    End;
end;

If someone wants to fix this up so it works properly and displays only normal keyboard characters (otherwise putting a "."), I would be happy to give the points.  Right now I think it has a bug where if it is under 16 bytes long, it displays incorrectly and gives an extra blank data line and stuff...

Was basically ported over from some buggy VBS source I found.  Just don't have a lot of time to fix minor things so I posted here...
0
 
LVL 7

Accepted Solution

by:
LRHGuy earned 50 total points
ID: 12081255
Try this...it seems to work perfectly, and you can change the number of characters per line..

procedure HexDisplay(var Data; Len:Integer);
const
  CharsPerLine=16;
var
  y1:Integer;
  iPos:Integer;
  sB,sT,sOffset:String;
type
  TByteArray=array[0..64000] of Byte;
var
  D:tByteArray absolute Data;
begin
  If Len=0 then
    Exit;

  ipos:=0;
  while iPos<Len do begin
    sOffset:=IntToHex(iPos,4);
    sT:='';
    sB:='';
    for y1:=1 to CharsPerLine do Begin
      if iPos>Len then
        Break;
      sB:=sB+' '+IntToHex(D[iPos],2);
      Case D[iPos] of
        ord(' ')..ord('~'): sT:=sT+Char(D[iPos])
        else                sT:=sT+'.';
      End; {case}
      iPos:=iPos+1;
    end;
    while length(sT)<CharsPerLine do begin
      sB:=sB+'   ';
      sT:=sT+' ';
    end;
    Form1.OutPutBox.Lines.Add(sOffset+': '+sB+' '+sT);
  End;
end;
0
 
LVL 7

Expert Comment

by:LRHGuy
ID: 12081262
BTW, that was in Delphi 7 so I hope it works in your version!
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:werehamster-
ID: 12081329
I use delphi 7 as well...
0
 
LVL 34

Expert Comment

by:Slick812
ID: 12081368
what I have for that


function HexDump2Str(Input: Pointer; Length: Integer): String;
var
posStr, HexStr, CharStr: String;
pos, i, top: Integer;
begin
Result := '';
if Length < 1 then Exit;
pos := 0;
while Length > 0 do
  begin
  posStr := IntToHex(pos, 8);
  HexStr := '';
  CharStr := '';
  if Length > 15 then
    top := 15
    else
    top := Length-1;
  for i := 0 to top do
    begin
    HexStr := HexStr+' '+IntToHex(PByteArray(Input)[pos+i], 2);
    if PByteArray(Input)[pos+i] in [32..126] then
      CharStr := CharStr+Chr(PByteArray(Input)[pos+i])
      else
      CharStr := CharStr+'.';
    end;
  if pos = 0 then
    Result := posStr+' '+HexStr+' '+CharStr
    else
    Result := Result+#13#10+posStr+' '+HexStr+' '+CharStr;
  Inc(pos, $10);
  Dec(Length, $10);
  end;

end;



procedure TForm1.button_HexDumpClick(Sender: TObject);
var
Str1: String;
begin
Str1 := #1#2#5'hello';
//Str1 := #4#16'Look Here for'#2#30'and more stuff'#222#188'Text to read';
Str1 := HexDump2Str(@Str1[1], Length(Str1));
Memo1.Text := Str1;
end;
0
 

Author Comment

by:werehamster-
ID: 12081401
Ok cool  I accepted his answer already though.  Both are cool.  LHRGuy seems to be what I am looking for though.  I may merge the two though.  :)

function HexDump2Str(var Data; Len:Integer) : String;
const
  CharsPerLine=16;
var
  y1:Integer;
  iPos:Integer;
  sB,sT,sOffset:String;
type
  TByteArray=array[0..64000] of Byte;
var
  D:tByteArray absolute Data;
begin
  If Len=0 then
    Exit;

  ipos:=0;
  while iPos<Len do begin
    sOffset:=IntToHex(iPos,4);
    sT:='';
    sB:='';
    for y1:=1 to CharsPerLine do Begin
      if iPos>Len then
        Break;
      sB:=sB+' '+IntToHex(D[iPos],2);
      Case D[iPos] of
        ord(' ')..ord('~'): sT:=sT+Char(D[iPos])
        else                sT:=sT+'.';
      End; {case}
      iPos:=iPos+1;
    end;
    while length(sT)<CharsPerLine do begin
      sB:=sB+'   ';
      sT:=sT+' ';
    end;
    if pos = 0 then
      Result := sOffset+': '+sB+' '+sT
    else
      Result := Result +#13#10 +sOffset+': '+sB+' '+sT;
  end;
end;
0
 

Author Comment

by:werehamster-
ID: 12081408
well, supposed to be ipos, case anyone else cuts and pastes.  I haven't tested it yet, but the combined version looks sound.  :)
0
 
LVL 34

Expert Comment

by:Slick812
ID: 12086505
you really should change the

function HexDump2Str(var Data; Len:Integer) : String;

to

function HexDump2Str(constr Data; Len:Integer) : String;

the const is much more efficient than the var,


function HexDump2Str(const Input; Length: Integer): String;
var
posStr, HexStr, CharStr: String;
pos, i, top, Value1: Integer;
begin
Result := '';
if Length < 1 then Exit;
pos := 0;
while Length > 0 do
  begin
  posStr := IntToHex(pos, 8);
  HexStr := ' ';
  CharStr := '  ';
  if Length > 15 then
    top := 15
    else
    top := Length-1;
  for i := 0 to top do
    begin
    Value1 := PByteArray(@Input)[pos+i];
    HexStr := HexStr+' '+IntToHex(Value1, 2);
    if Value1 in [32..126] then
      CharStr := CharStr+Chr(Value1)
      else
      CharStr := CharStr+'.';
    end;
    Result := Result+posStr+HexStr+CharStr+#13#10;
  Inc(pos, $10);
  Dec(Length, $10);
  end;

end;
0
 

Author Comment

by:werehamster-
ID: 12089815
Yeah I figured out after I tested it...  here is how I had to change it....

function HexDump2Str(const Data:string; Len:Integer) : String;
const
  CharsPerLine=16;
var
  y1:Integer;
  iPos:Integer;
  sB,sT,sOffset:String;
type
  TByteArray=array[0..64000] of Byte;
var
  D:tByteArray absolute Data;
begin
  Result := '';
  If Len=0 then
    Exit;
  ipos:=0;
  while iPos<(Len-1) do begin
    sOffset:=IntToHex(iPos,4);
    sT:='';
    sB:='';
    for y1:=1 to CharsPerLine do Begin
      if iPos>(Len-1) then
        Break;
      sB:=sB+' '+IntToHex(Ord(Data[iPos+1]),2);
      Case ord(Data[iPos+1]) of
        ord(' ')..ord('~'): sT:=sT+(Data[iPos+1])
        else                sT:=sT+'.';
      End; {case}
      iPos:=iPos+1;
    end;
    while length(sT)<CharsPerLine do begin
      sB:=sB+'   ';
      sT:=sT+' ';
    end;
    if Ipos <= CharsPerLine then
      Result := sOffset+': '+sB+' '+sT
    else
      Result := Result +#13#10 +sOffset+': '+sB+' '+sT;
  end;
end;
0
 

Author Comment

by:werehamster-
ID: 12139897
Just an update...

  if iPos>(Len-1) then


change to...

if iPos > Lent then


Otherwise if a line only has 1 byte, it would ignore it.  Case anyone else comes across this...
0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
If you're a developer or IT admin, you’re probably tasked with managing multiple websites, servers, applications, and levels of security on a daily basis. While this can be extremely time consuming, it can also be frustrating when systems aren't wor…
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…

734 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question