-
-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathmemoryScanner.js
81 lines (60 loc) · 2.47 KB
/
memoryScanner.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
const fs = require("fs");
function findPatternInBuffer(buffer, bytesRead, signature, mask) {
const bufferLength = bytesRead + signature.length - 1;
for (let i = 0; i <= bytesRead - signature.length; i++) {
if (isMatch(buffer, signature, mask, i)) return i;
}
return -1;
}
function isMatch(buffer, signature, mask, offset) {
for (let i = 0; i < signature.length; i++) {
if (mask[i] === "x" && buffer[offset + i] !== signature[i]) return false;
}
return true;
}
function parseSignature(signature) {
const signatureBytes = [];
let mask = "";
const tokens = signature.split(" ");
tokens.forEach((token) => {
if (token === "??" || token === "?") {
signatureBytes.push(0);
mask += "?";
} else {
signatureBytes.push(parseInt(token, 16));
mask += "x";
}
});
return { signature: Buffer.from(signatureBytes), mask };
}
async function patchBySignature(filePath, functionSignature, patchBytes, patchOffset) {
const { signature, mask } = parseSignature(functionSignature);
const bufferSize = 8192;
const buffer = Buffer.alloc(bufferSize + signature.length - 1);
const fileHandle = await fs.promises.open(filePath, "r+");
let filePosition = 0;
try {
while (true) {
const { bytesRead } = await fileHandle.read(buffer, 0, bufferSize, filePosition);
if (bytesRead === 0) break;
const matchIndex = findPatternInBuffer(buffer, bytesRead, signature, mask);
if (matchIndex !== -1) {
const functionStartPosition = filePosition + matchIndex;
const checkBuffer = Buffer.alloc(patchBytes.length);
await fileHandle.read(checkBuffer, 0, patchBytes.length, functionStartPosition + patchOffset);
if (Buffer.compare(checkBuffer, Buffer.from(patchBytes)) === 0) {
return 0; // Memory already patched
}
// Go to patch position
await fileHandle.write(Buffer.from(patchBytes), 0, patchBytes.length, functionStartPosition + patchOffset);
return functionStartPosition; // Return the address of the function start by signature
}
filePosition += bytesRead;
buffer.copy(buffer, 0, bufferSize, bufferSize + signature.length - 1);
}
} finally {
await fileHandle.close();
}
return -1;
}
module.exports = patchBySignature;