Archive: Hex to ASCII and back


Hex to ASCII and back
I'm working on modifying a hex file and I've searched but I haven't found a clear answer on this.

I just want to be able to open a file using FileOpen, find what I'm looking for with either FileSeek, unless there is an easier way, and then modify it using FileWriteByte and then FileClose.

I need to read the file in Hex, convert it to ASCII, then go from ASCII to Hex to write it again...even if I have to do some extra converts, that's the basic idea I have.

I'm only going to be changing one character, but I haven't found an easy way to do this.

Thanks in Advance for the help!


Alright, well, I've got it mostly figured out.

Here is what I used

IntFmt $2 "%C" "0x$1"


to do what I want...but now I've run into a new issue...

I need to read a certain hex out of this file here and I can't seem to figure out which byte to read.

The character I want is (I guess it depends on which editor you use) is the FIRST instance of 0x54 (letter: "T"). In one editor I used, it says the offset it 9 so..I don't know if that helps or not.

I just can't seem to seek to the right location and read the right byte so I can replace it.

This is where I'm currently at your mercy. Can anyone tell me what I should be using to get to this particular hex and read/write it??

I need to replace that exact hex 0x54 with another hex that'll be the same length, but could be almost any character from A-Z. Insight here would be extremely appreciated also.

Here is the code that I've been working with to get to where I want to be:

                FileOpen $0 "$PROFILEDIRECTORY\fstrees\$TREEFILE" a
FileSeek $0 9 SET $1
FileReadByte $1 $2
IntFmt $3 "%C" "0x$2"


as well as many variations thereof, but I can't find the right byte.

(I'm currently working on this in a PortableApps.com Launcher to portablize Songbird. And this file is part of their watch folders setup, in hex, so I have to edit this one character as it's the drive letter -- if this helps at all).

Again, Thanks in advance for any help.

And the file from the URL (in case it's stripped out of my message).


This code fragment might help you

  FileOpen $0 "$TREEFILE" a

FileSeek $0 9 SET
FileReadByte $0 $2
IntFmt $3 "%C" "$2"

DetailPrint "$$3 = '$3'"

FileClose $0
It produces this output when used with the sample file you supplied:
$3 = 'T'
Completed

Originally posted by pengyou
This code fragment might help you
  FileOpen $0 "$TREEFILE" a

FileSeek $0 9 SET
FileReadByte $0 $2
IntFmt $3 "%C" "$2"

DetailPrint "$$3 = '$3'"

FileClose $0
It produces this output when used with the sample file you supplied:
$3 = 'T'
Completed
THANK YOU!!! I'm so grateful I could kiss you!! (But I won't, that would be weird).

I tried 9, my issue must've been with the IntFmt using the 0x also instead of just the byte I read. OH well. I'm going to tinker some more, I have to convert bytes some more still. This is a huge help! :D thanks!

Now I can't format from string back to hex...

I'm using the following:

IntFmt $3 "%lX" "C"


and it returns nothing but "0". I've tried "%x", "%X", "%lx", "%lX" but none of them return nothing but "0". Am I doing something wrong? I've even tried adding "0x" in front of those and I still get nothing :(

There is a LogicLib.nsh function called ${CharToASCII} which helps when you need to manipulate ASCII codes.

See this wiki page for further details: http://nsis.sourceforge.net/CharToASCII

Here is a simple example which uses that function: http://forums.winamp.com/showthread....85#post2530285


I'm trying that now, when I include the CharToASCII I get the following error:

!define: "CharToASCII"="!insertmacro CharToASCII"
Function: "CharToASCII"
Exch($0,0)
Push: $1
Push: $2
StrCpy $2 "1" () ()
IntFmt: $2->$1 (fmt:%c)
Invalid command: ${If}
!include: error in script: "CharToASCII.nsh" on line 17

Did you include LogicLib.nsh in your script? You need to include that file in order to be able to use "${If}".

I need to correct my last reply: I should have said "There is a LogicLib.nsh-based function called ${CharToASCII} ..." because ${CharToASCII} is not actually included in LogicLib.nsh.


Oh wow...I apparently missed that. Lemme add it and try again.


Here's what I managed:

FileOpen $0 "$PROFILEDIRECTORY\fstrees\$TREEFILE" a
FileSeek $0 9 SET
FileReadByte $0 $1
IntFmt $2 "%C" "$1"
${StrStrip} ":" $LASTDRIVE $3
;StrCmp $2 $5
${CharToASCII} $4 $3
IntFmt $5 "%lX" "$4"


Where the character I'm reading from the .tree file is "T" and the character from last drive is "C" (at least in this case).

This returns what I need finally :)

Thanks pengyou, again, for all your help, even in my blatant stupidity :)

And ONE last nagging question.

I want to replace the byte that I've read, with the byte I just converted... I'm guessing something like this, but I don't think it's going to be this easy...is it?:

                FileOpen $0 "$PROFILEDIRECTORY\fstrees\$TREEFILE" a
FileSeek $0 9 SET
FileReadByte $0 $1
IntFmt $2 "%C" "$1"
${StrStrip} ":" $LASTDRIVE $3
;StrCmp $2 $3
${CharToASCII} $4 $3
IntFmt $5 "%lX" "$4"
FileWriteByte $0 $5
FileClose $0


Ignore the StrCmp for now, that's just so I don't forget I need that there.

I'm guessing something like this, but I don't think it's going to be this easy...is it?:
I think that was close but not quite there. Try something like this
FileOpen $0 "$PROFILEDIRECTORY\fstrees\$TREEFILE" a
FileSeek $0 9 SET
FileReadByte $0 $1
IntFmt $2 "%C" "$1"
${StrStrip} ":" $LASTDRIVE $3
;StrCmp $2 $3
${CharToASCII} $4 $3

FileSeek $0 9 SET
FileWriteByte $0 $4

FileClose $0

Wow...I'm not getting anywhere again, pulling my hair out.

I've attached my current .tree file.

Here's the code I'm using (explanation to follow):


FileOpen $0 "$PROFILEDIRECTORY\fstrees\$TREEFILE" a
FileSeek $0 9 SET
FileReadByte $0 $1
FileSeek $0 10 SET
FileReadByte $0 $7
IntFmt $2 "%C" "$1"
${StrStrip} ":" $CURRENTDRIVE $3
${CharToASCII} $4 $3
IntFmt $5 "%lX" "$4"
FileSeek $0 9 SET
FileWriteByte $0 $5
FileSeek $0 9 SET
FileReadByte $0 $6
FileSeek $0 1 SET
FileReadByte $0 $8
Messagebox MB_OK|MB_ICONEXCLAMATION `$1 -- $2 -- $3 -- $4 -- $5 -- $6 -- $7 -- $8`


Now, in here I'm trying to read the "F" and change it to a new letter, in my testing I was aiming for J.

I've added the Messagebox to show the variables (self-explanatory now), for debugging. What seems to be happening, is it reads the F fine, formats it to a character beautifully, and then it reads the currentdrive, J, encodes it correctly to the hex equivalent (4A), as shown by $5, but then when I read the Byte again, it only reads as "4" as shown by $6. $7 and $8 also both read as zero. When I look at the file again, the previous drive letter "F" was replaced with EOT, whose hex equivalent is "4". So it seems that only one byte is being written, not both??

I have to recode the $4 back to hex because that's how the file is stored, hence the IntFmt to create $5. Which, I checked, is the right hex value.

Do I have to just split and write the bytes separately?? I'm just kinda lost on why it's not working.

Don't worry, I plan on cleaning up the reads and whatnot after I get this debugged, I'm just trying to figure it out.

Thanks AGAIN. (I'm a pain, I know).

FileWriteByte writes a SINGLE byte to the file. ASCII characters fit into a SINGLE byte so to change the letter 'F' to the letter 'J' all you need to do is change a SINGLE byte.

Look again at the last code fragment I supplied. When I tested it the code was able to change the 'T' in your sample data to a 'Z'.

There is no need to do the hex conversion; notice that my code does NOT use IntFmt to convert the result from CharToASCII.

In my code the result from CharToASCII is written directly to the file. ASCII characters fit into a single byte so there is no need to do anything to the result before FileWriteByte is used to save the result in the file.

FileWriteByte only writes a single byte to the file (i.e. it writes a value between 0 and 255 or, if you prefer to think in hex, between 0x00 and 0xFF). If you supply a value that is too big to fit into a single byte, FileWriteByte will only write the bottom 8 bits, e.g. supply 256 and it will write 0 into the file.


Thank you!! I was overcomplicating it I suppose...it works beautifully without the IntFmt. I guess that just didn't click in my mind. Now it works as it should :) (So far).

Thanks again for everything pengyou!!!


Originally posted by Gizmokid2005
Now it works as it should :)
Glad to hear that you have got it working now.