C_to_PS1
C_to_PS1

Reputation: 53

Typecast bytes in powershell

In C, I have the following code

struct _file_header* file_header = (struct _file_header*)(cfg_bytes + (cfg_size - 16));

Which effectively fills the _file_header structure with the bytes from memory. I want to do the same thing in Powershell, but I am confused with the [System.Text.Encoding]::ASCII.GetBytes returning some bytes that aren't related to the data I see in cfg_bytes

Take the following PowerShell code,

$cfg_bytes   = (Get-Content $env:ProgramData'\config.bin' -Raw)
$cfg_size    = [System.Text.Encoding]::ASCI.GetByteCount($cfg_bytes)
$file_header = $cfg_bytes.Substring($cfg_size - 16, 16)

When I Write-Output [System.Text.Encoding]::ASCII.GetBytes($file_header), the output is not the same as I see from my debugger memory viewer. How can I obtain the bytes in the same format as the C example, such that I'd be able to read the same structure in PowerShell?

Upvotes: 2

Views: 353

Answers (1)

mklement0
mklement0

Reputation: 437953

As Santiago Squarzon suggests, use the following to directly get a file's raw bytes in PowerShell:

  • In Windows PowerShell:
$cfg_bytes = Get-Content -Encoding Byte -Raw $env:ProgramData\config.bin 
  • In PowerShell (Core) 7+:
$cfg_bytes = Get-Content -AsByteStream -Raw $env:ProgramData\config.bin 

Note: This breaking change in syntax between the two PowerShell editions is unfortunate, and arguably should never have happened - see GitHub issue #7986.

Note that adding -Raw to the Get-Content call - when combined with -Encoding Byte / -AsByteStream - efficiently returns all bytes as a single array, strongly typed as [byte[]].

Without -Raw, the bytes would be streamed - i.e., output to the pipeline one by one - which, if the output isn't accumulated, keeps memory use constant - but is much slower.

Upvotes: 3

Related Questions