Issue with replacing HEX values Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
Scr1pter
Posts: 1277
Joined: 06 Aug 2017, 08:21
Location: Germany

Issue with replacing HEX values

14 Apr 2024, 14:03

Hello,

I'm trying to replace HEX values in a MIDI file.
I used jNizM's great str2hex and hex2str functions.
Then I created two arrays: One with the search values and the other one with the replace values.

The script runs, but the output file is only 4 byte - the orig file was 1 kb.
Any idea what the problem could be?
FileRead, content, *c C:\1.mid did not work either, which is understandable.

Thanks for any help and best regards!

Code: Select all

F1::
FileRead, content, C:\1.mid
hexValue     := StringZuHex(content)
searchArray  := ["90\s+76", "90\s+74", "90\s+72", "90\s+6F"]
replaceArray := ["91 76", "91 74", "91 72", "91 6F"]

for index, search in searchArray
{
  replace  := replaceArray[index]
  hexValue := RegExReplace(hexValue, search, replace)
}
stringValue := HexZuString(hexValue)
FileAppend, %stringValue%, C:\1_new.mid
MsgBox, finished
return

StringZuHex(string)
{
  VarSetCapacity(bin, StrPut(string, "UTF-8")) && len := StrPut(string, &bin, "UTF-8") - 1 
  if !(DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", len, "uint", 0x4, "ptr", 0, "uint*", size))
  {
    throw Exception("CryptBinaryToString failed", -1)
  }
  VarSetCapacity(buf, size << 1, 0)
  if !(DllCall("crypt32\CryptBinaryToString", "ptr", &bin, "uint", len, "uint", 0x4, "ptr", &buf, "uint*", size))
  {
    throw Exception("CryptBinaryToString failed", -1)
  }    
  return StrGet(&buf)
}
HexZuString(string)
{
  if !(DllCall("crypt32\CryptStringToBinary", "ptr", &string, "uint", 0, "uint", 0x4, "ptr", 0, "uint*", size, "ptr", 0, "ptr", 0))
  {
    throw Exception("CryptStringToBinary failed", -1)
  }
  VarSetCapacity(buf, size, 0)
  if !(DllCall("crypt32\CryptStringToBinary", "ptr", &string, "uint", 0, "uint", 0x4, "ptr", &buf, "uint*", size, "ptr", 0, "ptr", 0))
  {
    throw Exception("CryptStringToBinary failed", -1)
  }
  return StrGet(&buf, size, "UTF-8")
}
Please use [code][/code] when posting code!
Keyboard: Logitech G PRO - Mouse: Logitech G502 LS - OS: Windows 10 Pro 64 Bit - AHK version: 1.1.33.09
User avatar
Scr1pter
Posts: 1277
Joined: 06 Aug 2017, 08:21
Location: Germany

Re: Issue with replacing HEX values

30 Apr 2024, 17:13

Hello again,

A while ago I found some code which just uses a simple StrReplace.
It was something like data := StrReplace(data, "{0xA}", "{0xB}

I tried that, but again, the output file was only 4 bytes...

I can open the file in Notepad++ and by using its HEX plugin I can actually see all the hex codes like:
4d 54 68 64 00 00 etc
Multiple search and replace works, but it's unstable, unreliable and slow.
Would much easier if I could just read in the file with AHK and perform multiple Replaces at once,
as I would do it for a normal text file.

I found this thread which is about WriteChar and it seems to work:
However, I would need the same for replacing rather than writing.
viewtopic.php?t=91324

Code: Select all

F1::
SetWorkingDir, %A_ScriptDir%
Filename =test.exe
HexEdit(Filename,  314, "000000000000000") ; write "........." at position  314
return
    
HexEdit(Filename, Position, Nibbles) 
{
    f := FileOpen(Filename, "rw")
    f.Seek(Position - 1)
    While StrLen(Nibbles) > 1 
    {
        f.WriteChar("0x" SubStr(Nibbles, 1, 2))
        Nibbles := SubStr(Nibbles, 3)
    }
    f.Close()
}
Any help will be appreciated
Thanks and best regards!
Please use [code][/code] when posting code!
Keyboard: Logitech G PRO - Mouse: Logitech G502 LS - OS: Windows 10 Pro 64 Bit - AHK version: 1.1.33.09
User avatar
Spawnova
Posts: 557
Joined: 08 Jul 2015, 00:12
Contact:

Re: Issue with replacing HEX values  Topic is solved

30 Apr 2024, 23:09

Perhaps someone will know a better way, but off the top of my head I would probably just open the file and loop through the bytes

Code: Select all

#NoEnv
#SingleInstance, Force
SendMode, Input
SetBatchLines, -1
SetWorkingDir, %A_ScriptDir%

;define the replacements
replace := []
replace.push({find:[0x90,0x76],rep:[0x91,0x76]})
replace.push({find:[0x90,0x74],rep:[0x91,0x74]})
replace.push({find:[0x90,0x72],rep:[0x91,0x72]})
replace.push({find:[0x90,0x6F],rep:[0x91,0x6F]})



count := ReplaceData("C:\1.mid",replace) ;replace the bytes

msgbox % "Replaced " count " matches"
exitapp



ReplaceData(file, replace, backup:=1) {

	f := fileopen(file,"rw") ;open midi file for reading and writing
	bytes := f.length
	if (bytes = 0) {
		f.close()
		return 0
	}
	varsetcapacity(data,bytes)
	f.rawread(data,bytes) ;read the data to a buffer

	if (backup) {
		ifnotexist,% file ".bak"
		{
			b := fileopen(file ".bak","w")
			b.rawwrite(data,bytes)
			b.close()
		}
	}

	repCount := 0
	for k,v in replace {
		findLen := v.find.length()
		if (findLen != v.rep.length())
			continue ; does not support extra data
		c := 1
		i := 0
		while(i < bytes) {
			char := numget(data,i,"uchar")
			if (char = v.find[c]) {
				if (c = findLen) {
					repCount++
					c := 1
					for kk,vv in v.rep {
						numput(vv,data,i-findLen+a_index,"uchar")
					}
				} else {
					c++
				}
			} else {
				if (c > 1) {
					i -= (c-1)
					c := 1
				}
			}
			i++
		}
	}

	f.pos := 0
	f.rawwrite(data,bytes)
	f.close() ;close the file
	return repCount
}

User avatar
Scr1pter
Posts: 1277
Joined: 06 Aug 2017, 08:21
Location: Germany

Re: Issue with replacing HEX values

03 May 2024, 15:16

Hello Spawnova,

I checked your script and it worked perfectly :bravo:
To be sure I double checked it with the other method (multiple replaces in NPP with Hex-Plugin)
and the result was 100% the same, but 10 times faster and much easier.

The cool thing is that it also replaces more than 2 values, e.g.
replace.push({find:[0x80, 0x52, 0x7F], rep:[0x83, 0x52, 0x7F]})

I was also a bit worried about the array length, but even 340 lines were no problem :)

Thank you :thumbup:
Please use [code][/code] when posting code!
Keyboard: Logitech G PRO - Mouse: Logitech G502 LS - OS: Windows 10 Pro 64 Bit - AHK version: 1.1.33.09

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: No registered users and 91 guests