v2.beta7 ReadProcessMemory access error (ok in v2.beta6) Topic is solved

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
neogna2
Posts: 586
Joined: 15 Sep 2016, 15:44

v2.beta7 ReadProcessMemory access error (ok in v2.beta6)

Post by neogna2 » 06 Aug 2022, 04:29

With v2.beta7 I get access error (0xc0000005) from DllCall to ReadProcessMemory (specifically code to read from the Scintilla control in a Notepad2 window). The same script throws no error with v2.beta6. I will post details and code to reproduce this later. But a quick question for now: Does beta7 have some intentional change that might affect ReadProcessMemory?

lexikos
Posts: 9552
Joined: 30 Sep 2013, 04:07
Contact:

Re: v2.beta7 ReadProcessMemory access error (ok in v2.beta6)

Post by lexikos » 07 Aug 2022, 22:39

When a script contains pointer or struct related errors, you will get "undefined behavior". That can mean the script crashes, throws exceptions, works perfectly but only on Tuesdays...

There may be some change in beta 7, but I think it is more likely that your script already contained an error and only worked by coincidence.

neogna2
Posts: 586
Joined: 15 Sep 2016, 15:44

Re: v2.beta7 ReadProcessMemory access error (ok in v2.beta6)

Post by neogna2 » 08 Aug 2022, 05:11

lexikos wrote:
07 Aug 2022, 22:39
I think it is more likely that your script already contained an error and only worked by coincidence.
Knowing me, yes probably :) But I've used that script a lot with beta6 so I suspect some change in beta7 matters here.

It seems in v2.beta7 my DllCall to ReadProcessMemory throws unless I provide return type "Int", like so
DllCall("ReadProcessMemory", "Ptr", hProcess, "Ptr", lpBaseAddress, "Ptr", oBuffer, "Int", BufferSize, "Int")
SelectedText := StrGet(oBuffer, BufferSize, "UTF-8")


Whereas in beta6 ReadProcessMemory works if I provide no return type.
DllCall("ReadProcessMemory", "Ptr", hProcess, "Ptr", lpBaseAddress, "Ptr", oBuffer, "Int", BufferSize)
But does not work with return type "Int". Does not work as in no error is thrown but StrGet on the ReadProcessMemory output buffer returns empty. Though if I use Try then using a return type works (i.e. StrGet returns text) also in beta6
Try DllCall("ReadProcessMemory", "Ptr", hProcess, "Ptr", lpBaseAddress, "Ptr", oBuffer, "Int", BufferSize, "Int")

For context: ReadProcessMemory returns BOOL and https://lexikos.github.io/v2/docs/commands/DllCall.htm says for both beta7 and beta6 that ReturnType may be omitted if BOOL
ReturnType: If the function returns a 32-bit signed integer (Int), BOOL, or nothing at all, ReturnType may be omitted. Otherwise, specify one of the argument types from the types table below. The asterisk suffix is also supported.
Edit:
Aha! I now noticed that my script (and above code snippets) omitted ReadProcessMemory's 5th parameter
BOOL ReadProcessMemory(
[in] HANDLE hProcess,
[in] LPCVOID lpBaseAddress,
[out] LPVOID lpBuffer,
[in] SIZE_T nSize,
[out] SIZE_T *lpNumberOfBytesRead
);
[...]
[out] lpNumberOfBytesRead A pointer to a variable that receives the number of bytes transferred into the specified buffer. If lpNumberOfBytesRead is NULL, the parameter is ignored.
This means that when I thought I above added ReturnType "Int" I actually added only a type for that 5th parameter. I don't know why there's a beta7/beta6 difference in that case.

But the following works for me in both beta6 and beta7 (no try or ReturnType needed).
DllCall("ReadProcessMemory", "Ptr", hProcess, "Ptr", lpBaseAddress, "Ptr", oBuffer, "Int", BufferSize, "Ptr", 0)

lexikos
Posts: 9552
Joined: 30 Sep 2013, 04:07
Contact:

Re: v2.beta7 ReadProcessMemory access error (ok in v2.beta6)

Post by lexikos » 08 Aug 2022, 22:28

So as I guessed, your script already contained an error and only worked by coincidence.

Adding an explicit "int" return type to DllCall slightly changes the content of the native call stack, which is where the parameters are supposed to be.

neogna2
Posts: 586
Joined: 15 Sep 2016, 15:44

Re: v2.beta7 ReadProcessMemory access error (ok in v2.beta6)  Topic is solved

Post by neogna2 » 09 Aug 2022, 03:20

lexikos wrote:
08 Aug 2022, 22:28
So as I guessed, your script already contained an error and only worked by coincidence.
Yes!

But something also changed with beta7. Because I tested a bit more and v2.beta1 to v2.beta6 accepts omitting ReadProcessMemory's 5th parameter in my script without any errors thrown, like so
DllCall("ReadProcessMemory", "Ptr", hProcess, "Ptr", lpBaseAddress, "Ptr", oBuffer, "Int", BufferSize)
With v2.beta7 that line throws an error.

I will mark the topic as solved since the solution is simply to add the missing 5th parameter (and pay more attention to Microsoft's doc :) )
DllCall("ReadProcessMemory", "Ptr", hProcess, "Ptr", lpBaseAddress, "Ptr", oBuffer, "Int", BufferSize, "Ptr", 0)

But I'm still a bit curious what change in beta7 might explain the difference, since the changelog does not mention DllCall changes. Did version <= beta6 autofill any omitted DllCall tail parameters with NULL whereas beta7 does not?

lexikos
Posts: 9552
Joined: 30 Sep 2013, 04:07
Contact:

Re: v2.beta7 ReadProcessMemory access error (ok in v2.beta6)

Post by lexikos » 10 Aug 2022, 22:24

As I said, it is a coincidence. By omitting the parameter, you are invoking undefined behaviour. The function looks for a fifth parameter next to the fourth parameter, but instead there is some other arbitrary value that was put there for some other purpose.

Of course something changed; bugs were fixed or features were added. Likely none of them had anything to do with this issue, but may have had a ripple effect on compiler optimization decisions or some-such.

Post Reply

Return to “Ask for Help (v2)”