0
votes

I'm trying to open a file and read the content inside a buffer using NSIS Installer. Unfortunatly, everything works except KERNEL32::ReadFile. I read that a lot of people have some problem with this API, and i can't find a solution.

Here is my code :

StrCpy $2 $2\TOS.TXT
System::Call 'Kernel32::CreateFile(t, i, i, i, i, i, i) i (r2, 0x80000000, 0, 0, 4, 0x80, 0) .r3' 
System::Call 'kernel32::GetFileSize(pr3, p0)i.r7' ; Call API to read 32-bit file size
System::Call "kernel32::VirtualAlloc(i0, ir7, i0x3000, i0x40) .r1"
System::Call "KERNEL32::ReadFile(pr3,pr1,ir7,*i,p0)i.r3"

The file is well opened and the buffer is well created with the correct size.

Any help is appreciated, Thank, Chris.

1
How do you know the file is opened correctly and that the size is correct? - Anders
@Anders Hello, i can't delete the file and i can see the buffer created with the correct size using process hacker. Also, i have create a messagebox earlier to output the size, it was correct. - Frenchy
@Anders I will change my question because it's not totally true. Everything works except ReadFile. I misspoke sorry. - Frenchy
Finaly problem seems to come with VirtualAlloc, cuz when i remplace VirtualAlloc by System::Call '*(&i$7,i0)p.r1' everything works well (exept i have 32 bytes no zero in the memory page). - Frenchy

1 Answers

0
votes

Your VirtualAlloc call is missing the output type before .r1.

There is no need to use the System plug-in just to read from a simple file.

!macro MakeTestFile
FileOpen $0 "$temp\nsis_test.txt" w
FileWrite $0 "Hello$\nWorld!"
FileClose $0
!macroend


StrCpy $9 "$temp\nsis_test.txt"

!insertmacro MakeTestFile
FileOpen $0 "$9" r
FileRead $0 $1 ; Line 1
FileRead $0 $2 ; Line 2
FileClose $0
MessageBox MB_OK $1$2

!insertmacro MakeTestFile
FileOpen $0 "$9" r
FileSeek $0 1 SET
FileReadByte $0 $1
FileClose $0
IntFmt $1 "0x%.2X" $1
MessageBox MB_OK "Byte #2 is $1"

!insertmacro MakeTestFile
System::Call 'KERNEL32::CreateFile(t, i, i, p, i, i, p) p (r9, 0x80000000, 0, 0, 4, 0x80, 0) .r3' 
System::Call 'KERNEL32::GetFileSize(pr3, p0)i.r7'
System::Call "KERNEL32::VirtualAlloc(p0, pr7, i0x3000, i0x40)p.r1"
System::Call "KERNEL32::ReadFile(pr3,pr1,ir7,*i,p0)i.r3"
System::Call "USER32::MessageBoxA(p$hwndparent,pr1,t 'System::Call',i0)"
System::Call "KERNEL32::VirtualFree(pr1,p0,i0x8000)"

The System plug-in also has System::Alloc/StrAlloc/Free so there is no need to call VirtualAlloc directly if you need memory.