We help IT Professionals succeed at work.

PowerShell: Find & Replace Hex Values

Member_2_8180951
on
2,016 Views
Last Modified: 2018-09-26
I need help writing a PowerShell script: write offset positions, find and replace hex value with another hex value in an entire file.

Similar to,
$Hex_Search = "0xFF 0xFF 0xFF" # White

Write-Host Found "$Hex_Search" Between Offsets: 0x00000500-0x00001000

$Hex_Replace = "0xC0 0xC0 0xC0" # Silver

Open in new window


For my script the file can be any size.
Been using two PowerShell scripts, no avail.
# Credit to OP

$path = "C:\_Test 2\Test.txt"

$numberOfBytesToRead = 1000000

$stringToSearch = "0xFF 0xFF 0xFF"
$enc = [system.Text.Encoding]::UTF8
[Byte[]]$replacementString = $enc.GetBytes("0xC0 0xC0 0xC0");

$fileStream = [System.IO.File]::Open($path, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite)

# binary reader to search for the string 
$binaryReader = New-Object System.IO.BinaryReader($fileStream)

# get the contents of the beginning of the file
[Byte[]] $byteArray = $binaryReader.ReadBytes($numberOfBytesToRead)

# look for string
$m = [Regex]::Match([Text.Encoding]::ASCII.GetString($byteArray), $stringToSearch)
if ($m.Success)
{    
    echo "Found '$stringToSearch' At Position "$m.Index
}
else
{
    echo "'$stringToSearch' Not Found"
}

$fileStream.Close()

# reopen to write
$fileStream = [System.IO.File]::Open($path, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Write, [System.IO.FileShare]::ReadWrite)

$binaryWriter = New-Object System.IO.BinaryWriter($fileStream)

# set file position to location of the string
$binaryWriter.BaseStream.Position = $m.Index; 
$binaryWriter.Write($replacementString)

$fileStream.Close()

Open in new window


(Get-Content "C:\_Test 2\Test.txt") | ForEach-Object {$_ -Replace '0xFF 0xFF 0xFF', '0xC0 0xC0 0xC0'} | Set-Content "C:\_Test 2\Test.txt"

Open in new window


Thanks In Advance
Comment
Watch Question

CERTIFIED EXPERT
Top Expert 2014

Commented:
Can you provide a couple sample files?
One in the format you're ingesting and that has the values you want to replace, and one that shows the file as it should be after processing.

This will be the easiest way to ensure there's no confusion around objectives, etc.
Michael B. SmithManaging Consultant
CERTIFIED EXPERT

Commented:
I think you may be overthinking this. :-)

[byte[]] $searchBytes = 0x3, 0x4, 0x5  ## whatever
[byte[]] $content = Get-Content -Path <filename> -Raw -ReadCount 0 -Encoding Byte
if( $content.Contains( $searchBytes ) )
{
    $startIndex = $content.IndexOf( $searchBytes )
    Write-Host "Found searchBytes at $startIndex"
    ## well, replace it and rewrite it - you already know how to do that
}

Open in new window

Author

Commented:
I don't have example files (apologies), I need to find and replace hex (and print the offset range positions) similar to,
$Find_example = (0x65 0x78 0x61 0x6d 0x70 0x6c 0x65) # example (in hex)
Write-Host Found "$Find_example" Between Offsets: 0x00000500-0x00001000 # Just Example Position Range
$Replace_With_next = (0x6e 0x65 0x78 0x74) # next (in hex)

Open in new window


I actually need to find and replace color hex code,
$Find_Color_Hex = (0x00 0x80 0x00) # green in hex proper hex code (#008000)
Write-Host Found "$Find_Color_Hex" Between Offsets: 0x00000500-0x00001000 # Just Example Position Range
$Replace_Color_Hex = (0x87 0xCE 0xEB) # skyblue in hex proper hex code(#87CEEB)

Open in new window


@Michael B. Smith thanks for an answer, but the parameter "-Raw" isn't in PowerShell v2 ;_;
CERTIFIED EXPERT
Top Expert 2014

Commented:
The files should be pretty trivial for you to create.  You've already got files you want to work on (hence your question).  Just strip out all but a few lines that include the match you're searching for (you can obfuscate other info if needed).  Save it and you've got your sample input.  Do a manual edit to create your desired result, save it and you've got your sample output.
Michael B. SmithManaging Consultant
CERTIFIED EXPERT

Commented:
Replace this line

[byte[] $content = Get-Content -Path <filename> -Raw -ReadCount 0 -Encoding Byte

with

[byte[] $content = [System.Io.File]::ReadAllBytes( <filename> )

To get (and I added the rest of it):

[byte[]] $searchBytes = 0x0, 0x80, 0x0  ## your example
[byte[]] $replaceBytes = 0x87, 0xCE, 0xEB  ## your example
[byte[]] $content = [System.Io.File]::ReadAllBytes( <filename> )
if( $content.Contains( $searchBytes ) )
{
    $startIndex = $content.IndexOf( $searchBytes )
    Write-Host "Found searchBytes at $startIndex"
    for( $i = 0; $i -lt $searchBytes.Length; $i++ )
    {
        $content[ $i + $startIndex ] = $replaceBytes[ $i ]
    }
    [System.Io.File]::WriteAllBytes( <filename>, $content )
}

Open in new window

Author

Commented:
Here is example in text document,
some hex values are: 0x49, 0x4B, 0x41 (IKA)
and need to change to: 0x6D, 0x75, 0x73, 0x75, 0x6D, 0x65 (musume)
and vice-versa

and print ranges, such as
0x00000000-0x00000002
0x00000053-0x00000055

@Michael B. Smith
I received error,
Error: "Method invocation failed because [System.Byte[] doesn't contain a method named 'Contains'." (Apologies, new to PowerShell.)

Edit: tried to upload text file? here is link to contents of Example.txt https://pastebin.com/pw1P9k2S
Michael B. SmithManaging Consultant
CERTIFIED EXPERT

Commented:
How old a version of .NET and PowerShell are you running?

I copy-and-paste what I wrote above and it works.

Author

Commented:
PowerShell v2.0
.NET v3.0
Michael B. SmithManaging Consultant
CERTIFIED EXPERT

Commented:
Word.

So the input and output lengths can be different?

Can there be multiple occurrences of the input string in the file?

Author

Commented:
Yes, input and output can be different lengths.

There can be more occurrences.
Managing Consultant
CERTIFIED EXPERT
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION

Author

Commented:
Many Thanks @Michael B. Smith ^^

@footech if you have an solution please post it, I want learn from it :)
CERTIFIED EXPERT
Top Expert 2014

Commented:
I've got nothing, as I was waiting on sample files.  I had some questions that the files would have definitively answered, much easier than my trying to type them out.

But no worries, I'm glad Michael's solution works for you.

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.