Comments (15)
lib/memoryjs.cc 693:
uintptr_t address = -1;
736:
Local<Value> argv[argc] = { String::NewFromUtf8(isolate, errorMessage), Number::New(isolate, address) };
https://v8docs.nodesource.com/node-10.15/d9/d29/classv8_1_1_number.html:
static Local< Number > | New (Isolate *isolate, double value)
After conversion to double, the value of address
in js is 18446744073709552000.000000, obviously the data overflowed.
Comparing signed and unsigned numbers produces a logical error.Exceptions may never be thrown?
from memoryjs.
@dsasmblr thanks, glad you've found it useful! I've also taken a look at the same example. The implementation of findPattern
seems correct, it's just that in this specific case the address lies outside of a module...
Opening up notepad.exe
, typing deez
and doing a Search for text
with UTF-16
checked shows two results:
0x2E84C1CB240
0x2E84C1FBBA0
Running this script (using one of the two addresses) shows the address doesn't lie inside of any modules, but lies inside of a single region:
const memoryjs = require('./index');
const processName = "notepad.exe";
const processObject = memoryjs.openProcess(processName);
const address = 0x2E84C1CB240;
const matchingModules = memoryjs
.getModules(processObject.th32ProcessID)
.filter(mod => address >= mod.modBaseAddr && address <= (mod.modBaseAddr + mod.modBaseSize));
const matchingRegions = memoryjs
.getRegions(processObject.handle)
.filter(region => address >= region.BaseAddress && address <= (region.BaseAddress + region.RegionSize));
console.log('modules', matchingModules);
console.log('regions', matchingRegions);
const pattern = "64 00 65 00 65 00 7A 00";
memoryjs.findPattern(processObject.handle, pattern, 0, 0, (error, address) => {
console.log(`error: ${error}, address: 0x${address.toString(16).toUpperCase()}`);
});
I've edited the source code so that findPattern
searches both modules and regions, so the output in this case finds a match:
$ node test
modules []
regions [
{
BaseAddress: 3196732375040,
AllocationBase: 3196732375040,
AllocationProtect: 4,
RegionSize: 659456,
State: 4096,
Protect: 4,
Type: 131072
}
]
error: , address: 0x2E84C1CB240
Searching all regions & modules takes too long, so it might be worth having a findPattern
that searches everything, and a findPattern
that will search just a specified module or region...
I think I'll change findPattern
to have the following implementations:
// search all modules + all regions
findPattern(handle, pattern, flags, patternOffset[, callback])
// search a specific module
findPattern(handle, moduleName, pattern, flags, patternOffset[, callback])
// search a specific region (will find the region or module the base address lies inside)
findPattern(handle, baseAddress, pattern, flags, patternOffset[, callback])
from memoryjs.
Hey, @Rob--! Thanks so much for taking the time to test and reply with all of that. I totally didn't think about exploring regions like that. I was incorrectly assuming that regions relative to the application's modules were already taken into consideration. Thanks for clarifying!
I like the findPattern
changes you've suggested, too. I think all three would be respectively beneficial.
Thanks again, Rob!
from memoryjs.
These changes are implemented in a32ceee.
New implementation of findPattern
is:
// search all modules + all regions
findPattern(handle, pattern, flags, patternOffset[, callback])
// search a specific module
findPattern(handle, moduleName, pattern, flags, patternOffset[, callback])
// search a specific region (will find the region or module the base address lies inside)
findPattern(handle, baseAddress, pattern, flags, patternOffset[, callback])
The signatureOffset
parameter has been removed from findPattern
to reduce the parameter count. The value of the parameter was just added to the memory address returned, so does not need to happen inside of this function.
I'll leave the issue open to take comments until I publish all the recent library changes to NPM.
from memoryjs.
Hey, is the process 32 or 64 bit? And did you recompile the library for the target architecture?
from memoryjs.
The process is 64bit. By "recompile for target architecture", do you mean running npm i memoryjs --arch=ia64
? I get an error, gyp ERR! stack Error: C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin\MSBuild.exe failed with exit code: 1
.
I recall getting gyp
to work in the first place was an absolute nightmare, is it possible I can download the 64bit compiled file(s) somewhere without having to compile them myself?
EDIT: Spent over an hour trying to solve the gyp error, still no luck.
from memoryjs.
I forgot to add, I am on Windows 10 64-bit.
from memoryjs.
Go inside node_modules/memoryjs
and run the command npm run build64
(or just run node-gyp clean configure build --arch=x64
) and it should recompile the library to work for 64 bit targets.
from memoryjs.
Funny how I found this out myself before I checked your response, but it's still not working correctly.
I have a notepad++.exe
(64bit) window open with the text WALDO
in it. I run this code:
const memoryjs = require('memoryjs')
const toPattern = str => Buffer.from(str).toString('hex').replace(/..\B/g, '$& ').toUpperCase()
memoryjs.openProcess('notepad++.exe', (error, p) => {
console.log(`Module: ${JSON.stringify(p, null, 2)}`)
let text = 'WALDO'
let pattern = toPattern(text).replace(/ /g, '')
console.log(`Pattern scanning ${text} as ${pattern}`)
memoryjs.findPattern(p.handle, 'notepad++.exe', pattern, memoryjs.READ, 0, 0, (error, offset) => {
console.log(`Offset found: ${offset} (Cheat Engine says: ${0x1D3035D12E4})`)
memoryjs.readMemory(p.handle, offset, memoryjs.STRING, (error, value) => {
console.log(`Data read: ${value}`)
})
})
})
And the console windows outputs this:
Module: {
"dwSize": 304,
"th32ProcessID": 5552,
"cntThreads": 5,
"th32ParentProcessID": 5736,
"pcPriClassBase": 8,
"szExeFile": "notepad++.exe",
"handle": 480,
"modBaseAddr": 140698537820160
}
Pattern scanning WALDO as 57414C444F
Offset found: 12894362189 (Cheat Engine says: 2005806158564)
The memoryjs.readMemory
function never even outputs anything, the process automatically terminates within 5 seconds.
But if instead of using the offset
variable I use the address Cheat Engine gave me after finding WALDO
, it does read the text WALDO
, so it works if you give it the address. It just can't find the correct address itself.
Not sure how to get the code markup to work since I used backticks in my code. Fixed.
By the way I know the compilation worked correctly because the memoryjs.node
file has the PE d
string near the header, as viewed in a hex editor, meaning it is indeed 64 bit.
Although if I download your memoryjs
project as a .zip
file and build it as 64bit, the memoryjs.node
file is 150kb
whereas when built after being installed as a dependency of my project, it is only 138kb
, which is strange.
from memoryjs.
Could you perhaps try the experiment yourself? How would you find the text WALDO
in an open notepad++.exe
window using your project?
Would be greatly appreciated ...
from memoryjs.
I've been needing this project to work so bad for 3 months lol ... I need to grab all text from the memory of a game and save it to a file. I can do this with a slightly modified Lua script inside Cheat Engine after the game is over but the text is not in chronological order (I don't know if this is intentional obfuscation or just an inherent aspect of Random Access Memory?) and I don't know Lua enough to make it do what your project does. I even tried OCR with capture2text
but because it's 99% accurate instead of 100% it caused some insurmountable problems that would take too long to explain here.
from memoryjs.
@MelerEcckmanLawler did you figure this out? I'm having the same issue.
from memoryjs.
Hey,
I'm not the best at c, so I'm not qualified enough to explain what I found, But I'll try.
The function findPattern will return an uintptr_t (unsigned int). In case the function doesn't find the module - the address returned is -1, and if the pattern wasn't found - it will return -2. Since unsigned ints don't support negative numbers, they are parsed wrong.
I changed memoryjs::findPattern and pattern::findPattern functions to return signed integers(intptr_t). after the change, the address returned was actually -2, so I understood there's an issue with my pattern.
I think there's something wrong with the implantation. that said.. you can still check the error message in a callback, and not rely on the address returned (Haven't tested it).
In my case, it still didn't help. I'm searching the memory of an emulator, so I have no module name since the actual data is allocated somewhere. I'm working on a new function that will receive a start address and size to search in. I also want to implement pattern search using std::search, since it gave me really good results very quickly. I will share it if it works at all 😄
from memoryjs.
import { findPattern, openProcess, readMemory } from 'memoryjs';
const processName = "Notepad.exe";
const process = openProcess(processName);
const pattern = "64 00 65 00 65 00 7A 00";
const deez = findPattern(process.handle, process.szExeFile, pattern, 0, 0, 0).toString(16).toUpperCase();
console.log(deez)
const deezMem = readMemory(process.handle, 0x2B7502D1AE0, "string");
console.log(deezMem);
By happenstance, I spent the evening attempting the same type of task, but in Notepad.exe
in Windows 11. It's a 64-bit target, which I've properly compiled for.
If I search for my string of interest ("deez", which I typed as the only word into a new instance of Notepad) via Cheat Engine, I see it in two memory addresses (scanning RWX memory and for Unicode strings).
I've noted elsewhere here that memoryjs doesn't support Unicode (yet?), so I thought that pattern-scanning for the bytes that make up the string would be a workaround, but that doesn't appear to be the case.
If I use the readMemory()
method and read bytes 0, 2, 4, and 6 directly from each of the two memory addresses I found via Cheat Engine, I can verify that the letters are 'd', 'e', 'e', and 'z' -- which matches the endianness I've specified as my byte pattern.
I'm not sure at this point if the issue is my understanding of utilizing the library thus far, or perhaps if there's an issue with the findPattern()
method (like the algorithm being used, if there's some type of conflict with how a Unicode pattern is interpreted even with this method, or something else).
I just wanted to chime in here and gather some thoughts. Thanks, everyone! (And thank you for the library, Rob--; I've really been enjoying using much of it thus far!)
from memoryjs.
Closing the issue since v3.5.1 has been published to NPM and includes these changes.
from memoryjs.
Related Issues (20)
- How to read shared memory channel? (Windows) HOT 5
- Reading an address that is a BigInt throwing errors? HOT 3
- The library can't read memory for me can someone help me figure it out? HOT 2
-
- Any way to get module exports? HOT 2
- Add "Windows only" to readme HOT 2
- Usage with electron HOT 2
- Just pushed a commit (3be70b051025327db5d5f54cd5a1f777dea75943) that I think should enable this now (not on NPM yet). I wasn't familiar with memory mapped files before working on this change, but from my little testing it seems like you should be able to replicate this C# logic with memoryjs now. Updated the README with an example ([documentation](https://github.com/Rob--/memoryjs#memory-mapped-files-1)). HOT 2
- Error reading BigInt pointer HOT 6
- Feature: Open process using th32ProcessID instead of process name(multiple processes same name) HOT 2
- functionTest.cpp does not work on x64 builds HOT 1
- Using Cheat Engine Pointer HOT 6
- Writing to an adres using pointers HOT 2
- Little Endian Support HOT 3
- add pointer or int64 parameters on callFunction?
- publish/release newest version to npm? :) HOT 2
- Linux/Unix support HOT 2
- setProtection is not available in latest version HOT 1
- Problems when using with electron. HOT 1
- Hi Rob, HOT 8
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from memoryjs.