Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to read memory address bigger than 0xFFFFFFFF #9

Closed
Mystraht opened this issue Oct 15, 2017 · 16 comments
Closed

Unable to read memory address bigger than 0xFFFFFFFF #9

Mystraht opened this issue Oct 15, 2017 · 16 comments

Comments

@Mystraht
Copy link

Mystraht commented Oct 15, 2017

Hello,

I built memoryjs with npm run build64 but when i try to read memory with address that is bigger than 0xFFFFFFFF, it read wrong address.

For example, if i try to read address 0x141EA3612, it will return value of address 0x41EA3612 instead of 0x141EA3612 one.

My attached process is built with a 64bit architecture.

Do you have some idea to fix this ? Thanks

@Mystraht
Copy link
Author

Mystraht commented Oct 17, 2017

I found why bug happen.

In memory.h, the type of the second parameter is DWORD instead of DWORD64.
It's why we cant pass number that is bigger than 32bits uint maximum value.

I fix it by replacing DWORD to DWORD64.

But we have another problem, in memoryjs.cc line 348, we get function argument with args[0]->Uint32Value() method, this break number that is bigger than 4294967295.

I'm not native C programmer so i quickfix that by adding 4294967296 to args[0]->Uint32Value()

int result = Memory.readMemory<int>(process::hProcess, 4294967296 + args[0]->Uint32Value());

This way i can handle 64 bits memory address

@JaiPe
Copy link

JaiPe commented Apr 14, 2018

#14 Should help fix this?

@LiamKarlMitchell
Copy link
Contributor

LiamKarlMitchell commented Jul 28, 2018

Was there a better type to use that was sized depending on what it's compiled for.
DWORD_PTR or was it LPVOID but would need a way to transmit the x64 numbers through to native?

Is there really no Uint64Value methods?
Seems not... https://bugs.chromium.org/p/v8/issues/detail?id=1339
Mozilla have a draft idea on this though. https://developer.mozilla.org/en-US/docs/Mozilla/js-ctypes/js-ctypes_reference/UInt64

We could pass parameters with buffers.
https://community.risingstack.com/using-buffers-node-js-c-plus-plus/

Or have the wrapper function pass an extra argument to flag it as an x64address then just internally in the native add the amount or subtract the amount.

Or by use of another module?
https://github.com/candu/node-int64-native

ffi gets around it by returning strings as double-precision floating point numbers are imprecise.
https://www.npmjs.com/package/ffi#v8-and-64-bit-types

A solution could also take into consideration if the methods should work with other architecture.
Undocumented methods also exist to read/write x64 from x86 but seems hacky....

@karlrobertjanicki
Copy link

I found out that uintptr_t is only part of the answer. https://github.com/Rob--/memoryjs/pull/14
After changing Uint32Value() to IntegerValue() in readMemory and DWORD to DWORD64 for the base address it was possible to get the correct values in 64 bit programs for pointers as well as for values.

@karlrobertjanicki
Copy link

You can see the changes in 3792f5d

@Rob--
Copy link
Owner

Rob-- commented Dec 14, 2018

@karlrobertjanicki awesome, it seems as though IntegerValue is the solution for 64 bit integers:

V8EXPORT uint32_t v8::Value::Uint32Value() const;
V8EXPORT int64_t v8::Value::IntegerValue() const;

In your fork you don't replace all instances of Uint32Value() with IntegerValue() though? Any time an address is passed from the Node.js user space to the add-on we should use IntegerValue() to access it. I will look into updating the library soon with the relevant fixes.

Thanks!

@karlrobertjanicki
Copy link

I didn't replace all the instances of Uint32Value() with IntegerValue() because I only used pointer, float and dword. Long story short: because of laziness ;)

@Rob--
Copy link
Owner

Rob-- commented Dec 15, 2018

@karlrobertjanicki added in 646eb28.
Hopefully the library will be much more 64 bit compatible. Soon I will add explicit types such as int32_t, uint32_t and int64_t. Right now, the library's int type is simply int32_t.

Also, there is no support for getting type uint64_t from v8::Value (but there is support for int64_t). One solution I've seen for this is getting the double value (NumberValue()) and casting it to uint64_t.

@Rob--
Copy link
Owner

Rob-- commented Dec 15, 2018

Closing for now, if there is still problems with 64 bit compatibility I will reopen the issue!

@Rob-- Rob-- closed this as completed Dec 15, 2018
@karlrobertjanicki
Copy link

Thank you

@karlrobertjanicki
Copy link

@Rob--
Copy link
Owner

Rob-- commented Dec 20, 2018

@karlrobertjanicki addressed in abc9ee0.

@karlrobertjanicki
Copy link

Perfect :)

@karlrobertjanicki
Copy link

I have used memoryjs in a project. You can see the results on youtube
https://www.youtube.com/watch?v=gNiegwbILPg

@Rob--
Copy link
Owner

Rob-- commented Jun 9, 2019

@karlrobertjanicki Interesting project and awesome video!

@karlrobertjanicki
Copy link

Thank you. Without memoryjs this would not be possible. Awesome work

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants