zeeh3
30th June 2013 14:47 UTC
Hex Strings and lpBuffer
When using System::Call 'Kernel32::ReadFile(i r0, i r2, i r1, *i .r3, i 0)', $2 is a lpBuffer, a pointer to the buffer that receives the data read from a file. Is it possible to pass a hexadecimal string to a buffer like $2, instead of creating a file, writing the hexadecimal string to the file, reading the file to fill the $2 buffer and erasing the file to do what I want?
aerDNA
30th June 2013 17:37 UTC
There may be a more elegant way than how I do it, but here's a working example:
Outfile BufferStuffer.exe
Var Buffer
Var DataSize
!macro FillBuffer Data # Hex string expected for Data
StrLen $DataSize ${Data}
IntOp $DataSize $DataSize / 2
System::Alloc $DataSize
Pop $Buffer
StrCpy $9 0
IntOp $0 $9 * 2
StrCpy $0 ${Data} 2 $0
System::Call "*$Buffer(&v$9, &i1 '0x$0')"
IntOp $9 $9 + 1
IntCmp $9 $DataSize 0 -4
!macroend
!define FillBuffer "!insertmacro FillBuffer"
Function .onInit
${FillBuffer} "497420776F726B7321"
FileOpen $R0 "$EXEDIR\doesitwork.txt" w
System::Call "kernel32::WriteFile(i R0, i $Buffer, i $DataSize, *i.r1, i '') i.r0"
FileClose $R0
System::Free $Buffer
IntCmp $0 0 +2
IntCmp $1 $Datasize +2
MessageBox MB_OK|MB_ICONSTOP "Error writing file."
Abort
FunctionEnd
Section Blank
SectionEnd
zeeh3
30th June 2013 20:03 UTC
Thank you, I will try it :)
zeeh3
2nd July 2013 16:44 UTC
It works fine, but is pretty slow with big strings.
aerDNA
2nd July 2013 17:59 UTC
Well, one System call for every byte of data, you can't expect turbo performance if you need to process more than a few KB. It's not appropriate for that. Maybe someone knows a way to fill the buffer in a single pass, I don't, apart from the one you know as well - ReadFile. I don't know what your goal is, is it patching of some sort? A FileWriteByte loop should be faster than my example, no buffer required. Vpatch would be a perfect solution, if applicable.
[Edit] Did some testing: a FileWriteByte variant turned out approx. 3x faster for the same input/output.
aerDNA
2nd July 2013 18:39 UTC
You're processing a load of 511B chunks because of maxstrlen, that's what the question about iterating through gflags in that other thread was about, right? Packing it all up in a binary file you'd extract at runtime and load with ReadFile really would be way faster and 'cleaner'.
zeeh3
2nd July 2013 21:27 UTC
Yes, that's correct. I am now getting the data as a resource.
aerDNA
2nd July 2013 23:20 UTC
RCData? Nice solution.