{"id":13656346,"url":"https://github.com/Rob--/memoryjs","last_synced_at":"2025-04-23T22:30:43.954Z","repository":{"id":45301834,"uuid":"47046896","full_name":"Rob--/memoryjs","owner":"Rob--","description":"Read and write process memory in Node.js (Windows API functions exposed via Node bindings)","archived":false,"fork":false,"pushed_at":"2024-07-26T13:15:38.000Z","size":411,"stargazers_count":651,"open_issues_count":23,"forks_count":92,"subscribers_count":18,"default_branch":"master","last_synced_at":"2025-04-08T06:35:26.361Z","etag":null,"topics":["cpp","game-hacking","hacking","javascript","memory","memory-hacking","node-addon","nodejs","npm-package","winapi","windowsapi"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Rob--.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-11-29T02:23:12.000Z","updated_at":"2025-03-30T17:15:44.000Z","dependencies_parsed_at":"2024-01-14T16:13:33.304Z","dependency_job_id":"7685f1e5-5ab4-4eb3-8428-845ec3fbc09d","html_url":"https://github.com/Rob--/memoryjs","commit_stats":{"total_commits":133,"total_committers":10,"mean_commits":13.3,"dds":"0.23308270676691734","last_synced_commit":"f95e382136e2ee1318d0b57dc9a4ba5fd75fce1d"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rob--%2Fmemoryjs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rob--%2Fmemoryjs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rob--%2Fmemoryjs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rob--%2Fmemoryjs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Rob--","download_url":"https://codeload.github.com/Rob--/memoryjs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250526363,"owners_count":21445171,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpp","game-hacking","hacking","javascript","memory","memory-hacking","node-addon","nodejs","npm-package","winapi","windowsapi"],"created_at":"2024-08-02T05:00:18.753Z","updated_at":"2025-04-23T22:30:43.667Z","avatar_url":"https://github.com/Rob--.png","language":"C++","readme":"\u003cp align=\"center\"\u003e\n  \u003cimg width=\"600\" src=\"assets/logo.png\"\u003e\n  \u003cbr\u003e\n  \u003ccode\u003ememoryjs\u003c/code\u003e is a an NPM package to read and write process memory!\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://img.shields.io/github/license/Rob--/memoryjs\" alt=\"GitHub License\"\u003e\n  \u003cimg src=\"https://img.shields.io/npm/v/memoryjs.svg?style=flat\" alt=\"NPM Version\"\u003e\n  \u003cimg src=\"https://img.shields.io/npm/dy/memoryjs\" alt=\"NPM Downloads\"\u003e\n\u003c/p\u003e\n\n---\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"#user-content-features\"\u003eFeatures\u003c/a\u003e •\n  \u003ca href=\"#user-content-getting-started\"\u003eGetting Started\u003c/a\u003e •\n  \u003ca href=\"#user-content-usage\"\u003eUsage\u003c/a\u003e •\n  \u003ca href=\"#user-content-documentation\"\u003eDocumentation\u003c/a\u003e •\n  \u003ca href=\"#user-content-debug\"\u003eDebug\u003c/a\u003e\n\u003c/p\u003e\n\n\n# Features\n\n- List all open processes\n- List all modules associated with a process\n- Close process/file handles\n- Find a specific module within a process\n- Read and write process memory (w/big-endian support)\n- Read and write buffers (arbitrary structs)\n- Change memory protection\n- Reserve/allocate, commit or change regions of memory\n- Fetch a list of memory regions within a process\n- Pattern scanning\n- Execute a function within a process\n- Hardware breakpoints (find out what accesses/writes to this address, etc)\n- Inject \u0026 unload DLLs\n- Read memory mapped files\n\nTODO:\n- WriteFile support (for driver interactions)\n- Async/await support\n\n# Getting Started\n\n## Install\n\nThis is a Node add-on (last tested to be working on `v14.15.0`) and therefore requires [node-gyp](https://github.com/nodejs/node-gyp) to use.\n\nYou may also need to [follow these steps](https://github.com/nodejs/node-gyp#user-content-installation) to install and setup `node-gyp`.\n\n```bash\nnpm install memoryjs\n```\n\nWhen using memoryjs, the target process should match the platform architecture of the Node version running.\nFor example if you want to target a 64 bit process, you should try and use a 64 bit version of Node.\n\nYou also need to recompile the library and target the platform you want. Head to the memoryjs node module directory, open up a terminal and run one of the following compile scripts:\n\n```bash\n# will automatically compile based on the detected Node architecture\nnpm run build\n\n# compile to target 32 bit processes\nnpm run build32\n\n# compile to target 64 bit processes\nnpm run build64\n```\n\n## Node Webkit / Electron\n\nIf you are planning to use this module with Node Webkit or Electron, take a look at [Liam Mitchell](https://github.com/LiamKarlMitchell)'s build notes [here](https://github.com/Rob--/memoryjs/issues/23).\n\n# Usage\n\n## Initialise\n``` javascript\nconst memoryjs = require('memoryjs');\nconst processName = \"csgo.exe\";\n```\n\n## Processes\n- Open a process\n- Get all processes\n- Close a process (release handle)\n\n```javascript\n// sync: open a process\nconst processObject = memoryjs.openProcess(processName);\n\n// async: open a process\nmemoryjs.openProcess(processName, (error, processObject) =\u003e {});\n\n\n// sync: get all processes\nconst processes = memoryjs.getProcesses();\n\n// async: get all processes\nmemoryjs.getProcesses((error, processes) =\u003e {});\n\n\n// close a process (release handle)\nmemoryjs.closeHandle(handle);\n```\n\nSee the [Documentation](#user-content-process-object) section of this README to see what a process object looks like.\n\n## Modules \n- Find a module\n- Get all modules\n\n``` javascript\n// sync: find a module\nconst moduleObject = memoryjs.findModule(moduleName, processId);\n\n// async: find a module\nmemoryjs.findModule(moduleName, processId, (error, moduleObject) =\u003e {});\n\n\n// sync: get all modules\nconst modules = memoryjs.getModules(processId);\n\n// async: get all modules\nmemoryjs.getModules(processId, (error, modules) =\u003e {});\n```\n\nSee the [Documentation](#user-content-module-object) section of this README to see what a module object looks like.\n\n## Memory\n- Read data type from memory\n- Read buffer from memory\n- Write data type to memory\n- Write buffer to memory\n- Fetch memory regions\n\n``` javascript\n// sync: read data type from memory\nconst value = memoryjs.readMemory(handle, address, dataType);\n\n// async: read data type from memory\nmemoryjs.readMemory(handle, address, dataType, (error, value) =\u003e {});\n\n\n// sync: read buffer from memory\nconst buffer = memoryjs.readBuffer(handle, address, size);\n\n// async: read buffer from memory\nmemoryjs.readBuffer(handle, address, size, (error, buffer) =\u003e {});\n\n\n// sync: write data type to memory\nmemoryjs.writeMemory(handle, address, value, dataType);\n\n\n// sync: write buffer to memory\nmemoryjs.writeBuffer(handle, address, buffer);\n\n\n// sync: fetch memory regions\nconst regions = memoryjs.getRegions(handle);\n\n// async: fetch memory regions\nmemoryjs.getRegions(handle, (regions) =\u003e {});\n```\n\nSee the [Documentation](#user-content-documentation) section of this README to see what values `dataType` can be.\n\n## Memory Mapped Files\n- Open a named file mapping object\n- Map a view of a file into a specified process\n- Close handle to the file mapping object\n\n```javascript\n// sync: open a named file mapping object\nconst fileHandle = memoryjs.openFileMapping(fileName);\n\n\n// sync: map entire file into a specified process\nconst baseAddress = memoryjs.mapViewOfFile(processHandle, fileName);\n\n\n// sync: map portion of a file into a specified process\nconst baseAddress = memoryjs.mapViewOfFile(processHandle, fileName, offset, viewSize, pageProtection);\n\n\n// sync: close handle to a file mapping object\nconst success = memoryjs.closeHandle(fileHandle);\n```\n\nSee the [Documentation](#user-content-documentation) section of this README to see details on the parameters and return values for these functions.\n\n## Protection\n- Change/set the protection on a region of memory\n  \n```javascript\n// sync: change/set the protection on a region of memory\nconst oldProtection = memoryjs.virtualProtectEx(handle, address, size, protection);\n```\n\nSee the [Documentation](#user-content-protection-type) section of this README to see what values `protection` can be.\n\n## Pattern Scanning\n- Pattern scan all modules and memory regions\n- Pattern scan a given module\n- Pattern scan a memory region or module at the given base address\n\n```javascript\n// sync: pattern scan all modules and memory regions\nconst address = memoryjs.findPattern(handle, pattern, flags, patternOffset);\n\n// async: pattern scan all modules and memory regions\nmemoryjs.findPattern(handle, pattern, flags, patternOffset, (error, address) =\u003e {});\n\n\n// sync: pattern scan a given module\nconst address = memoryjs.findPattern(handle, moduleName, pattern, flags, patternOffset);\n\n// async: pattern scan a given module\nmemoryjs.findPattern(handle, moduleName, pattern, flags, patternOffset, (error, address) =\u003e {});\n\n\n// sync: pattern scan a memory region or module at the given base address\nconst address = memoryjs.findPattern(handle, baseAddress, pattern, flags, patternOffset);\n\n// async: pattern scan a memory region or module at the given base address\nmemoryjs.findPattern(handle, baseAddress, pattern, flags, patternOffset, (error, address) =\u003e {});\n```\n\n## Function Execution\n- Execute a function in a remote process\n\n``` javascript\n// sync: execute a function in a remote process\nconst result = memoryjs.callFunction(handle, args, returnType, address);\n\n// async: execute a function in a remote process\nmemoryjs.callFunction(handle, args, returnType, address, (error, result) =\u003e {});\n```\n\nClick [here](#user-content-result-object) to see what a result object looks like.\n\nClick [here](#user-content-function-execution-1) for details about how to format the arguments and the return type.\n\n## DLL Injection\n- Inject a DLL\n- Unload a DLL by module base address\n- Unload a DLL by module name\n\n```javascript\n// sync: inject a DLL\nconst success = memoryjs.injectDll(handle, dllPath);\n\n// async: inject a DLL\nmemoryjs.injectDll(handle, dllPath, (error, success) =\u003e {});\n\n\n// sync: unload a DLL by module base address\nconst success = memoryjs.unloadDll(handle, moduleBaseAddress);\n\n// async: unload a DLL by module base address\nmemoryjs.unloadDll(handle, moduleBaseAddress, (error, success) =\u003e {});\n\n\n// sync: unload a DLL by module name\nconst success = memoryjs.unloadDll(handle, moduleName);\n\n// async: unload a DLL by module name\nmemoryjs.unloadDll(handle, moduleName, (error, success) =\u003e {});\n```\n\n## Hardware Breakpoints\n- Attach debugger\n- Detach debugger\n- Wait for debug event\n- Handle debug event\n- Set hardware breakpoint\n- Remove hardware breakpoint\n\n``` javascript\n// sync: attach debugger\nconst success = memoryjs.attachDebugger(processId, exitOnDetach);\n\n// sync: detach debugger\nconst success = memoryjs.detachDebugger(processId);\n\n// sync: wait for debug event\nconst success = memoryjs.awaitDebugEvent(hardwareRegister, millisTimeout);\n\n// sync: handle debug event\nconst success = memoryjs.handleDebugEvent(processId, threadId);\n\n// sync: set hardware breakpoint\nconst success = memoryjs.setHardwareBreakpoint(processId, address, hardwareRegister, trigger, length);\n\n// sync: remove hardware breakpoint\nconst success = memoryjs.removeHardwareBreakpoint(processId, hardwareRegister);\n```\n\n# Documentation\n\nNote: this documentation is currently being updated, refer to the [Wiki](https://github.com/Rob--/memoryjs/wiki) for more information.\n\n## Process Object\n``` javascript\n{ dwSize: 304,\n  th32ProcessID: 10316,\n  cntThreads: 47,\n  th32ParentProcessID: 7804,\n  pcPriClassBase: 8,\n  szExeFile: \"csgo.exe\",\n  modBaseAddr: 1673789440,\n  handle: 808 }\n```\n\nThe `handle` and `modBaseAddr` properties are only available when opening a process and not when listing processes.\n\n## Module Object\n``` javascript\n{ modBaseAddr: 468123648,\n  modBaseSize: 80302080,\n  szExePath: 'c:\\\\program files (x86)\\\\steam\\\\steamapps\\\\common\\\\counter-strike global offensive\\\\csgo\\\\bin\\\\client.dll',\n  szModule: 'client.dll',\n  th32ProcessID: 10316,\n  GlblcntUsage: 2 }\n  ```\n\n## Result Object\n``` javascript\n{ returnValue: 1.23,\n  exitCode: 2 }\n```\n\nThis object is returned when a function is executed in a remote process:\n- `returnValue` is the value returned from the function that was called\n- `exitCode` is the termination status of the thread\n\n## Data Types\n\nWhen using the write or read functions, the data type (dataType) parameter should reference a constant from within the library:\n\n| Constant          | Bytes | Aliases                            | Range |\n|-------------------|-------|------------------------------------|-------|\n| `memoryjs.BOOL`   | 1     | `memoryjs.BOOLEAN`                 | 0 to 1 |\n| `memoryjs.INT8`   | 1     | `memoryjs.BYTE`, `memoryjs.CHAR`   | -128 to 127 |\n| `memoryjs.UINT8`  | 1     | `memoryjs.UBYTE`, `memoryjs.UCHAR` | 0 to 255 |\n| `memoryjs.INT16`  | 2     | `memoryjs.SHORT`                   | -32,768 to 32,767 |\n| `memoryjs.UINT16` | 2     | `memoryjs.USHORT`, `memoryjs.WORD` | 0 to 65,535 |\n| `memoryjs.INT32`  | 4     | `memoryjs.INT`, `memoryjs.LONG`    | -2,147,483,648 to 2,147,483,647 |\n| `memoryjs.UINT32` | 4     | `memoryjs.UINT`, `memoryjs.ULONG`, `memoryjs.DWORD` |\t0 to 4,294,967,295 |\n| `memoryjs.INT64`  | 8     | n/a                                | -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 |\n| `memoryjs.UINT64` | 8     | n/a                                | 0 to 18,446,744,073,709,551,615 |\n| `memoryjs.FLOAT`  | 4     | n/a                                | 3.4E +/- 38 (7 digits) |\n| `memoryjs.DOUBLE` | 8     | n/a                                | 1.7E +/- 308 (15 digits) |\n| `memoryjs.PTR`    | 4/8   | `memoryjs.POINTER`                 | n/a |\n| `memoryjs.UPTR`   | 4/8   | `memoryjs.UPOINTER`                | n/a |\n| `memoryjs.STR`    | n/a   | `memoryjs.STRING`                  | n/a |\n| `memoryjs.VEC3`   | 12    | `memoryjs.VECTOR3`                 | n/a |\n| `memoryjs.VEC4`   | 16    | `memoryjs.VECTOR4`                 | n/a |\n\n\nNotes:\n- all functions that accept an address also accept the address as a BigInt\n- pointer will be 4 bytes in a 32 bit build, and 8 bytes in a 64 bit build.\n- to read in big-endian mode, append `_BE` to the data type. For example: `memoryjs.DOUBLE_BE`.\n- when writing 64 bit integers (`INT64`, `UINT64`, `INT64_BE`, `UINT64_BE`) you will need to supply a [BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt). When reading a 64 bit integer, you will receive a BigInt.\n\nThese data types are to used to denote the type of data being read or written.\n\n64 bit integer example:\n```javascript\nconst value = memoryjs.readMemory(handle, address, memoryjs.INT64);\nconsole.log(typeof value); // bigint\nmemoryjs.writeMemory(handle, address, value + 1n, memoryjs.INT64);\n```\n\nVector3 is a data structure of three floats:\n```javascript\nconst vector3 = { x: 0.0, y: 0.0, z: 0.0 };\nmemoryjs.writeMemory(handle, address, vector3, memoryjs.VEC3);\n```\n\nVector4 is a data structure of four floats:\n```javascript\nconst vector4 = { w: 0.0, x: 0.0, y: 0.0, z: 0.0 };\nmemoryjs.writeMemory(handle, address, vector4, memoryjs.VEC4);\n```\n\n## Generic Structures\n\nIf you have a structure you want to write to memory, you can use buffers. For an example on how to do this, view the [buffers example](https://github.com/Rob--/memoryjs/blob/master/examples/buffers.js).\n\nTo write/read a structure to/from memory, you can use [structron](https://github.com/LordVonAdel/structron) to define your structures and use them to write or parse buffers.\n\nIf you want to read a `std::string` using `structron`, the library exposes a custom type that can be used to read/write strings:\n```javascript\n// To create the type, we need to pass the process handle, base address of the\n// structure, and the target process architecture (either \"32\" or \"64\").\nconst stringType = memoryjs.STRUCTRON_TYPE_STRING(processObject.handle, structAddress, '64');\n\n// Create a custom structure using the custom type, full example in /examples/buffers.js\nconst Struct = require('structron');\nconst Player = new Struct()\n  .addMember(string, 'name');\n```\n\nAlternatively, you can use the [concentrate](https://github.com/deoxxa/concentrate) and [dissolve](https://github.com/deoxxa/dissolve) libraries to achieve the same thing. An old example of this is [here](https://github.com/Rob--/memoryjs/blob/aa6ed7d302fb1ac315aaa90558db43d128746912/examples/buffers.js).\n\n## Protection Type\n\nProtection type is a bit flag DWORD value.\n\nThis parameter should reference a constant from the library:\n\n`memoryjs.PAGE_NOACCESS, memoryjs.PAGE_READONLY, memoryjs.PAGE_READWRITE, memoryjs.PAGE_WRITECOPY, memoryjs.PAGE_EXECUTE, memoryjs.PAGE_EXECUTE_READ, memoryjs.PAGE_EXECUTE_READWRITE, memoryjs.PAGE_EXECUTE_WRITECOPY, memoryjs.PAGE_GUARD, memoryjs.PAGE_NOCACHE, memoryjs.PAGE_WRITECOMBINE, memoryjs.PAGE_ENCLAVE_THREAD_CONTROL, memoryjs.PAGE_TARGETS_NO_UPDATE, memoryjs.PAGE_TARGETS_INVALID, memoryjs.PAGE_ENCLAVE_UNVALIDATED`\n\nRefer to MSDN's [Memory Protection Constants](https://docs.microsoft.com/en-gb/windows/desktop/Memory/memory-protection-constants) for more information.\n\n## Memory Allocation Type\n\nMemory allocation type is a bit flag DWORD value.\n\nThis parameter should reference a constat from the library:\n\n`memoryjs.MEM_COMMIT, memoryjs.MEM_RESERVE, memoryjs.MEM_RESET, memoryjs.MEM_RESET_UNDO`\n\nRefer to MSDN's [VirtualAllocEx](https://docs.microsoft.com/en-us/windows/desktop/api/memoryapi/nf-memoryapi-virtualallocex) documentation for more information.\n\n## Strings\n\nYou can use this library to read either a \"string\", or \"char*\" and to write a string.\n\nIn both cases you want to get the address of the char array:\n\n```c++\nstd::string str1 = \"hello\";\nstd::cout \u003c\u003c \"Address: 0x\" \u003c\u003c hex \u003c\u003c (DWORD) str1.c_str() \u003c\u003c dec \u003c\u003c std::endl;\n\nchar* str2 = \"hello\";\nstd::cout \u003c\u003c \"Address: 0x\" \u003c\u003c hex \u003c\u003c (DWORD) str2 \u003c\u003c dec \u003c\u003c std::endl;\n```\n\nFrom here you can simply use this address to write and read memory.\n\nThere is one caveat when reading a string in memory however, due to the fact that the library does not know\nhow long the string is, it will continue reading until it finds the first null-terminator. To prevent an\ninfinite loop, it will stop reading if it has not found a null-terminator after 1 million characters.\n\nOne way to bypass this limitation in the future would be to allow a parameter to let users set the maximum\ncharacter count.\n\n### Signature Type\n\nWhen pattern scanning, flags need to be raised for the signature types. The signature type parameter needs to be one of the following:\n\n`0x0` or `memoryjs.NORMAL` which denotes a normal signature.\n\n`0x1` or `memoryjs.READ` which will read the memory at the address.\n\n`0x2` or `memoryjs.SUBSTRACT` which will subtract the image base from the address.\n\nTo raise multiple flags, use the bitwise OR operator: `memoryjs.READ | memoryjs.SUBTRACT`.\n\n## Memory Mapped Files\n\nThe library exposes functions to map obtain a handle to and read a memory mapped file.\n\n**openFileMapping(fileName)**\n- *fileName*: name of the file mapping object to be opened\n- returns: handle to the file mapping object\n\nRefer to [MSDN's OpenFileMappingA](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-openfilemappinga) documentation for more information.\n\n**mapViewOfFile(processHandle, fileName)**\n- *processHandle*: the target process to map the file to\n- *fileHandle*: handle of the file mapping object, obtained by `memoryjs.openFileMapping`\n- Description: maps the entire file to target process' memory. Page protection defaults to `constants.PAGE_READONLY`.\n- Returns: the base address of the mapped file\n\n**mapViewOfFile(processHandle, fileName, offset, viewSize, pageProtection)**\n- *processHandle*: the target process to map the file to\n- *fileHandle*: handle of the file mapping object, obtained by `memoryjs.openFileMapping`\n- *offset* (`number` or `bigint`): the offset from the beginning of the file (has to be multiple of 64KB)\n- *viewSize* (`number` or `bigint`): the number of bytes to map (if `0`, the entire file will be read, regardless of offset)\n- *pageProtection*: desired page protection\n- Description: maps a view of the file to the target process' memory\n- Returns: the base address of the mapped file\n\nRefer to [MSDN's MapViewOfFile2](https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-mapviewoffile2) documentation for more information.\n\nSee [Protection Type](#user-content-protection-type) for page protection types.\n\n### Example\nWe have a process that creates a file mapping:\n```c++\nHANDLE fileHandle = CreateFileA(\"C:\\\\foo.txt\", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);\nHANDLE fileMappingHandle = CreateFileMappingA(fileHandle, NULL, PAGE_READONLY, 0, 0, \"MappedFooFile\");\n```\n\nWe can map the file to a specified target process and read the file with `memoryjs`:\n```javascript\nconst processObject = memoryjs.openProcess(\"example.exe\");\nconst fileHandle = memoryjs.openFileMapping(\"MappedFooFile\");\n\n// read entire file\nconst baseAddress = memoryjs.mapViewOfFile(processObject.handle, fileHandle.handle);\nconst data = memoryjs.readMemory(processObject.handle, baseAddress, memoryjs.STR);\n\n// read 10 bytes after 64KB\nconst baseAddress = memoryjs.mapViewOfFile(processObject.handle, fileHandle.handle, 65536, 10, constants.PAGE_READONLY);\nconst buffer = memoryjs.readBuffer(processObject.handle, baseAddress, 10);\nconst data = buffer.toString();\n\nconst success = memoryjs.closeHandle(fileHandle);\n```\n\nIf you want to read a memory mapped file without having a target process to map the file to, you can map it to the current Node process with global variable `process.pid`:\n```javascript\nconst processObject = memoryjs.openProcess(process.pid);\n```\n\n## Function Execution\n\nRemote function execution works by building an array of arguments and dynamically generating shellcode that is injected into the target process and executed, for this reason crashes may occur.\n\nTo call a function in a process, the `callFunction` function can be used. The library supports passing arguments to the function and need to be in the following format:\n\n```javascript\n[{ type: T_INT, value: 4 }]\n```\n\nThe library expects the arguments to be an array of objects where each object has a `type` which denotes the data type of the argument, and a `value` which is the actual value of the argument. The various supported data types can be found below.\n\n\n``` javascript\nmemoryjs.T_VOID = 0x0,\nmemoryjs.T_STRING = 0x1,\nmemoryjs.T_CHAR = 0x2,\nmemoryjs.T_BOOL = 0x3,\nmemoryjs.T_INT = 0x4,\nmemoryjs.T_DOUBLE = 0x5,\nmemoryjs.T_FLOAT = 0x6,\n```\n\nWhen using `callFunction`, you also need to supply the return type of the function, which again needs to be one of the above values.\n\nFor example, given the following C++ function:\n\n``` c++\nint add(int a, int b) {\n    return a + b;\n}\n```\n\nYou would call this function as so:\n\n```javascript\nconst args = [{\n    type: memoryjs.T_INT,\n    value: 2,\n}, {\n    type: memoryjs.T_INT,\n    value: 5,\n}];\nconst returnType = T_INT;\n\n\u003e memoryjs.callFunction(handle, args, returnType, address);\n{ returnValue: 7, exitCode: 7 }\n```\n\nSee the [result object documentation](user-content-result-object) for details on what `callFunction` returns.\n\nNotes: currently passing a `double` as an argument is not supported, but returning one is.\n\nMuch thanks to the [various contributors](https://github.com/Rob--/memoryjs/issues/6) that made this feature possible.\n\n## Hardware Breakpoints\n\nHardware breakpoints work by attaching a debugger to the process, setting a breakpoint on a certain address and declaring a trigger type (e.g. breakpoint on writing to the address) and then continuously waiting for a debug event to arise (and then consequently handling it).\n\nThis library exposes the main functions, but also includes a wrapper class to simplify the process. For a complete code example, checkout our [debugging example](https://github.com/Rob--/memoryjs/blob/master/examples/debugging.js).\n\nWhen setting a breakpoint, you are required to pass a trigger type:\n- `memoryjs.TRIGGER_ACCESS` - breakpoint occurs when the address is accessed\n- `memoryjs.TRIGGER_WRITE` - breakpoint occurs when the address is written to\n\nDo note that when monitoring an address containing a string, the `size` parameter of the `setHardwareBreakpoint` function should be the length of the string. When using the `Debugger` wrapper class, the wrapper will automatically determine the size of the string by attempting to read it.\n\nTo summarise:\n- When using the `Debugger` class:\n  - No need to pass the `size` parameter to `setHardwareBreakpoint`\n  - No need to manually pick a hardware register\n  - Debug events are picked up via an event listener\n  - `setHardwareBreakpoint` returns the register that was used for the breakpoint\n\n- When manually using the debugger functions:\n  - The `size` parameter is the size of the variable in memory (e.g. int32 = 4 bytes). For a string, this parameter is the length of the string\n  - Manually need to pick a hardware register (via `memoryjs.DR0` through `memoryhs.DR3`). Only 4 hardware registers are available (some CPUs may even has less than 4 available). This means only 4 breakpoints can be set at any given time\n  - Need to manually wait for debug and handle debug events\n  - `setHardwareBreakpoint` returns a boolean stating whether the operation as successful\n\nFor more reading about debugging and hardware breakpoints, checkout the following links:\n- [DebugActiveProcess](https://msdn.microsoft.com/en-us/library/windows/desktop/ms679295(v=vs.85).aspx) - attaching the debugger\n- [DebugSetProcessKillOnExit](https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-debugsetprocesskillonexit) - kill the process when detaching\n- [DebugActiveProcessStop](https://msdn.microsoft.com/en-us/library/windows/desktop/ms679296(v=vs.85).aspx) - detaching the debugger\n- [WaitForDebugEvent](https://msdn.microsoft.com/en-us/library/windows/desktop/ms681423(v=vs.85).aspx) - waiting for the breakpoint to be triggered\n- [ContinueDebugEvent](https://msdn.microsoft.com/en-us/library/windows/desktop/ms679285(v=vs.85).aspx) - handling the event\n\n### Using the Debugger Wrapper:\n\nThe Debugger wrapper contains these functions you should use:\n\n``` javascript\nclass Debugger {\n  attach(processId, killOnDetach = false);\n  detach(processId);\n  setHardwareBreakpoint(processId, address, trigger, dataType);\n  removeHardwareBreakpoint(processId, register);\n}\n```\n\n1. Attach the debugger\n``` javascript\nconst hardwareDebugger = memoryjs.Debugger;\nhardwareDebugger.attach(processId);\n```\n\n2. Set a hardware breakpoint\n``` javascript\nconst address = 0xDEADBEEF;\nconst trigger = memoryjs.TRIGGER_ACCESS;\nconst dataType = memoryjs.INT;\nconst register = hardwareDebugger.setHardwareBreakpoint(processId, address, trigger, dataType);\n```\n\n3. Create an event listener for debug events (breakpoints)\n``` javascript\n// `debugEvent` event emission catches debug events from all registers\nhardwareDebugger.on('debugEvent', ({ register, event }) =\u003e {\n  console.log(`Hardware Register ${register} breakpoint`);\n  console.log(event);\n});\n\n// You can listen to debug events from specific hardware registers\n// by listening to whatever register was returned from `setHardwareBreakpoint`\nhardwareDebugger.on(register, (event) =\u003e {\n  console.log(event);\n});\n```\n\n### When Manually Debugging:\n\n1. Attach the debugger\n``` javascript\nconst hardwareDebugger = memoryjs.Debugger;\nhardwareDebugger.attach(processId);\n```\n\n2. Set a hardware breakpoint (determine which register to use and the size of the data type)\n``` javascript\n// available registers: DR0 through DR3\nconst register = memoryjs.DR0;\n// int = 4 bytes\nconst size = 4;\n\nconst address = 0xDEADBEEF;\nconst trigger = memoryjs.TRIGGER_ACCESS;\nconst dataType = memoryjs.INT;\n\nconst success = memoryjs.setHardwareBreakpoint(processId, address, register, trigger, size);\n```\n\n3. Create the await/handle debug event loop\n``` javascript\nconst timeout = 100;\n\nsetInterval(() =\u003e {\n  // `debugEvent` can be null if no event occurred\n  const debugEvent = memoryjs.awaitDebugEvent(register, timeout);\n\n  // If a breakpoint occurred, handle it\n  if (debugEvent) {\n    memoryjs.handleDebugEvent(debugEvent.processId, debugEvent.threadId);\n  }\n}, timeout);\n```\n\nNote: a loop is not required, e.g. no loop required if you want to simply wait until the first detection of the address being accessed or written to.\n\n# Debug\n\n### 1. Re-compile the project to be debugged\n\nGo to the root directory of the module and run one of the following commands:\n```bash\n# will automatically compile based on the detected Node architecture\nnpm run debug\n\n# compile to target 32 bit processes\nnpm run debug32\n\n# compile to target 64 bit processes\nnpm run debug64\n```\n\n### 2. Change the `index.js` file to require the debug module\n\nGo to the root directory and change the line in `index.js` from:\n```javascript\nconst memoryjs = require('./build/Release/memoryjs');\n```\n\nTo the following:\n```javascript\nconst memoryjs = require('./build/Debug/memoryjs');\n```\n\n### 3. Open the project in Visual Studio\n\nOpen the `binding.sln` solution in Visual Studio, found in the `build` folder in the project's root directory.\n\n### 4. Setup Visual Studio debug configuration\n\n  1. In the toolbar, click \"Project\" then \"Properties\"\n  2. Under \"Configuration Properties\", click \"Debugging\"\n  3. Set the \"Command\" property to the location of your `node.exe` file (e.g. `C:\\nodejs\\node.exe`)\n  4. Set the \"Command Arguments\" property to the location of your script file (e.g. `C:\\project\\test.js`)\n\n### 5. Set breakpoints\n\nExplore the project files in Visual Studio (by expanding `..` and then `lib` in the Solution Explorer). Header files can be viewed by holding `Alt` and clicking on the header file names at the top of the source code files.\n\nBreakpoints are set by clicking to the left of the line number.\n\n### 6. Run the debugger\n\nStart debugging by either pressing `F5`, by clicking \"Debug\" in the toolbar and then \"Start Debugging\", or by clicking \"Local Windows Debugger\".\n\nThe script you've set as the command argument in step 4 will be run, and Visual Studio will pause on the breakpoints set and allow you to step through the code line by line and inspect variables.\n","funding_links":[],"categories":["C++"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FRob--%2Fmemoryjs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FRob--%2Fmemoryjs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FRob--%2Fmemoryjs/lists"}