@cheatron/native-mock 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +21 -0
- package/dist/constants.d.ts +175 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +173 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/kernel32.d.ts +22 -0
- package/dist/kernel32.d.ts.map +1 -0
- package/dist/kernel32.js +170 -0
- package/dist/logger.d.ts +2 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +2 -0
- package/dist/os/handles.d.ts +17 -0
- package/dist/os/handles.d.ts.map +1 -0
- package/dist/os/handles.js +21 -0
- package/dist/os/kernel.d.ts +18 -0
- package/dist/os/kernel.d.ts.map +1 -0
- package/dist/os/kernel.js +50 -0
- package/dist/os/memory.d.ts +24 -0
- package/dist/os/memory.d.ts.map +1 -0
- package/dist/os/memory.js +147 -0
- package/dist/os/process.d.ts +17 -0
- package/dist/os/process.d.ts.map +1 -0
- package/dist/os/process.js +35 -0
- package/dist/os/thread.d.ts +40 -0
- package/dist/os/thread.d.ts.map +1 -0
- package/dist/os/thread.js +64 -0
- package/dist/process.d.ts +30 -0
- package/dist/process.d.ts.map +1 -0
- package/dist/process.js +124 -0
- package/dist/thread.d.ts +28 -0
- package/dist/thread.d.ts.map +1 -0
- package/dist/thread.js +113 -0
- package/package.json +59 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Cheatron
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# @cheatron/cheatron-native-mock
|
|
2
|
+
|
|
3
|
+
This package provides a pure JavaScript/TypeScript mock implementation of `@cheatron/cheatron-native`.
|
|
4
|
+
|
|
5
|
+
It simulates the Windows API (`Kernel32`) and core classes (`Process`, `Thread`) in memory, allowing tests and development on non-Windows platforms without native dependencies.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **In-Memory Kernel32**: Simulates memory operations, handle management, and process/thread APIs.
|
|
10
|
+
- **Type-Safe**: Uses `win32-def` for accurate Windows API type definitions.
|
|
11
|
+
- **Dependency-Free**: Removes `koffi` and `win32-api` runtime dependencies.
|
|
12
|
+
- **Test Compatibility**: Passes the standard `@cheatron/cheatron-native` test suite.
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
This package is intended for testing and development environments where native modules cannot be loaded.
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
bun install
|
|
20
|
+
bun test
|
|
21
|
+
```
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process access rights
|
|
3
|
+
* https://learn.microsoft.com/en-us/windows/win32/procthread/process-security-and-access-rights
|
|
4
|
+
*/
|
|
5
|
+
export declare const ProcessAccess: {
|
|
6
|
+
readonly TERMINATE: 1;
|
|
7
|
+
readonly CREATE_THREAD: 2;
|
|
8
|
+
readonly SET_SESSIONID: 4;
|
|
9
|
+
readonly VM_OPERATION: 8;
|
|
10
|
+
readonly VM_READ: 16;
|
|
11
|
+
readonly VM_WRITE: 32;
|
|
12
|
+
readonly DUP_HANDLE: 64;
|
|
13
|
+
readonly CREATE_PROCESS: 128;
|
|
14
|
+
readonly SET_QUOTA: 256;
|
|
15
|
+
readonly SET_INFORMATION: 512;
|
|
16
|
+
readonly QUERY_INFORMATION: 1024;
|
|
17
|
+
readonly SUSPEND_RESUME: 2048;
|
|
18
|
+
readonly QUERY_LIMITED_INFORMATION: 4096;
|
|
19
|
+
readonly SET_LIMITED_INFORMATION: 8192;
|
|
20
|
+
readonly ALL_ACCESS: 2097151;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Thread access rights
|
|
24
|
+
* https://learn.microsoft.com/en-us/windows/win32/procthread/thread-security-and-access-rights
|
|
25
|
+
*/
|
|
26
|
+
export declare const ThreadAccess: {
|
|
27
|
+
readonly TERMINATE: 1;
|
|
28
|
+
readonly SUSPEND_RESUME: 2;
|
|
29
|
+
readonly GET_CONTEXT: 8;
|
|
30
|
+
readonly SET_CONTEXT: 16;
|
|
31
|
+
readonly SET_INFORMATION: 32;
|
|
32
|
+
readonly QUERY_INFORMATION: 64;
|
|
33
|
+
readonly SET_THREAD_TOKEN: 128;
|
|
34
|
+
readonly IMPERSONATE: 256;
|
|
35
|
+
readonly DIRECT_IMPERSONATION: 512;
|
|
36
|
+
readonly SET_LIMITED_INFORMATION: 1024;
|
|
37
|
+
readonly QUERY_LIMITED_INFORMATION: 2048;
|
|
38
|
+
readonly ALL_ACCESS: 2097151;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Memory protection constants
|
|
42
|
+
* https://learn.microsoft.com/en-us/windows/win32/memory/memory-protection-constants
|
|
43
|
+
*/
|
|
44
|
+
export declare const MemoryProtection: {
|
|
45
|
+
readonly NOACCESS: 1;
|
|
46
|
+
readonly READONLY: 2;
|
|
47
|
+
readonly READWRITE: 4;
|
|
48
|
+
readonly WRITECOPY: 8;
|
|
49
|
+
readonly EXECUTE: 16;
|
|
50
|
+
readonly EXECUTE_READ: 32;
|
|
51
|
+
readonly EXECUTE_READWRITE: 64;
|
|
52
|
+
readonly EXECUTE_WRITECOPY: 128;
|
|
53
|
+
readonly GUARD: 256;
|
|
54
|
+
readonly NOCACHE: 512;
|
|
55
|
+
readonly WRITECOMBINE: 1024;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Memory state constants
|
|
59
|
+
*/
|
|
60
|
+
export declare const MemoryState: {
|
|
61
|
+
readonly COMMIT: 4096;
|
|
62
|
+
readonly RESERVE: 8192;
|
|
63
|
+
readonly FREE: 65536;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Memory type constants
|
|
67
|
+
*/
|
|
68
|
+
export declare const MemoryType: {
|
|
69
|
+
readonly PRIVATE: 131072;
|
|
70
|
+
readonly MAPPED: 262144;
|
|
71
|
+
readonly IMAGE: 16777216;
|
|
72
|
+
};
|
|
73
|
+
export type ProcessAccessValue = (typeof ProcessAccess)[keyof typeof ProcessAccess];
|
|
74
|
+
export type ThreadAccessValue = (typeof ThreadAccess)[keyof typeof ThreadAccess];
|
|
75
|
+
/**
|
|
76
|
+
* MEMORY_BASIC_INFORMATION structure
|
|
77
|
+
* https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-memory_basic_information
|
|
78
|
+
*/
|
|
79
|
+
export interface MemoryBasicInformation {
|
|
80
|
+
BaseAddress: number | bigint;
|
|
81
|
+
AllocationBase: number | bigint;
|
|
82
|
+
AllocationProtect: number;
|
|
83
|
+
RegionSize: number | bigint;
|
|
84
|
+
State: number;
|
|
85
|
+
Protect: number;
|
|
86
|
+
Type: number;
|
|
87
|
+
}
|
|
88
|
+
export declare const MEMORY_BASIC_INFORMATION: {
|
|
89
|
+
name: string;
|
|
90
|
+
spec: unknown;
|
|
91
|
+
};
|
|
92
|
+
export declare const MBI_SIZE: 1 | 2 | 4 | 8 | 16 | 48 | 1232;
|
|
93
|
+
export declare const ContextFlags: {
|
|
94
|
+
readonly AMD64: 1048576;
|
|
95
|
+
readonly CONTROL: number;
|
|
96
|
+
readonly INTEGER: number;
|
|
97
|
+
readonly SEGMENTS: number;
|
|
98
|
+
readonly FLOATING_POINT: number;
|
|
99
|
+
readonly DEBUG_REGISTERS: number;
|
|
100
|
+
readonly FULL: number;
|
|
101
|
+
readonly ALL: number;
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* M128A structure (128-bit register value)
|
|
105
|
+
* https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-m128a
|
|
106
|
+
*/
|
|
107
|
+
export declare const M128A: {
|
|
108
|
+
name: string;
|
|
109
|
+
spec: unknown;
|
|
110
|
+
};
|
|
111
|
+
export interface M128AValue {
|
|
112
|
+
Low: bigint;
|
|
113
|
+
High: bigint;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* CONTEXT structure for x64 (AMD64)
|
|
117
|
+
* https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-context
|
|
118
|
+
*/
|
|
119
|
+
export declare const CONTEXT: {
|
|
120
|
+
name: string;
|
|
121
|
+
spec: unknown;
|
|
122
|
+
};
|
|
123
|
+
export declare const CONTEXT_SIZE: 1 | 2 | 4 | 8 | 16 | 48 | 1232;
|
|
124
|
+
/**
|
|
125
|
+
* Parsed thread context (x64)
|
|
126
|
+
*/
|
|
127
|
+
export interface ThreadContext {
|
|
128
|
+
P1Home: bigint;
|
|
129
|
+
P2Home: bigint;
|
|
130
|
+
P3Home: bigint;
|
|
131
|
+
P4Home: bigint;
|
|
132
|
+
P5Home: bigint;
|
|
133
|
+
P6Home: bigint;
|
|
134
|
+
ContextFlags: number;
|
|
135
|
+
MxCsr: number;
|
|
136
|
+
SegCs: number;
|
|
137
|
+
SegDs: number;
|
|
138
|
+
SegEs: number;
|
|
139
|
+
SegFs: number;
|
|
140
|
+
SegGs: number;
|
|
141
|
+
SegSs: number;
|
|
142
|
+
EFlags: number;
|
|
143
|
+
Dr0: bigint;
|
|
144
|
+
Dr1: bigint;
|
|
145
|
+
Dr2: bigint;
|
|
146
|
+
Dr3: bigint;
|
|
147
|
+
Dr6: bigint;
|
|
148
|
+
Dr7: bigint;
|
|
149
|
+
Rax: bigint;
|
|
150
|
+
Rcx: bigint;
|
|
151
|
+
Rdx: bigint;
|
|
152
|
+
Rbx: bigint;
|
|
153
|
+
Rsp: bigint;
|
|
154
|
+
Rbp: bigint;
|
|
155
|
+
Rsi: bigint;
|
|
156
|
+
Rdi: bigint;
|
|
157
|
+
R8: bigint;
|
|
158
|
+
R9: bigint;
|
|
159
|
+
R10: bigint;
|
|
160
|
+
R11: bigint;
|
|
161
|
+
R12: bigint;
|
|
162
|
+
R13: bigint;
|
|
163
|
+
R14: bigint;
|
|
164
|
+
R15: bigint;
|
|
165
|
+
Rip: bigint;
|
|
166
|
+
FltSave: number[];
|
|
167
|
+
VectorRegister: M128AValue[];
|
|
168
|
+
VectorControl: bigint;
|
|
169
|
+
DebugControl: bigint;
|
|
170
|
+
LastBranchToRip: bigint;
|
|
171
|
+
LastBranchFromRip: bigint;
|
|
172
|
+
LastExceptionToRip: bigint;
|
|
173
|
+
LastExceptionFromRip: bigint;
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process access rights
|
|
3
|
+
* https://learn.microsoft.com/en-us/windows/win32/procthread/process-security-and-access-rights
|
|
4
|
+
*/
|
|
5
|
+
export const ProcessAccess = {
|
|
6
|
+
TERMINATE: 0x0001,
|
|
7
|
+
CREATE_THREAD: 0x0002,
|
|
8
|
+
SET_SESSIONID: 0x0004,
|
|
9
|
+
VM_OPERATION: 0x0008,
|
|
10
|
+
VM_READ: 0x0010,
|
|
11
|
+
VM_WRITE: 0x0020,
|
|
12
|
+
DUP_HANDLE: 0x0040,
|
|
13
|
+
CREATE_PROCESS: 0x0080,
|
|
14
|
+
SET_QUOTA: 0x0100,
|
|
15
|
+
SET_INFORMATION: 0x0200,
|
|
16
|
+
QUERY_INFORMATION: 0x0400,
|
|
17
|
+
SUSPEND_RESUME: 0x0800,
|
|
18
|
+
QUERY_LIMITED_INFORMATION: 0x1000,
|
|
19
|
+
SET_LIMITED_INFORMATION: 0x2000,
|
|
20
|
+
ALL_ACCESS: 0x1fffff,
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Thread access rights
|
|
24
|
+
* https://learn.microsoft.com/en-us/windows/win32/procthread/thread-security-and-access-rights
|
|
25
|
+
*/
|
|
26
|
+
export const ThreadAccess = {
|
|
27
|
+
TERMINATE: 0x0001,
|
|
28
|
+
SUSPEND_RESUME: 0x0002,
|
|
29
|
+
GET_CONTEXT: 0x0008,
|
|
30
|
+
SET_CONTEXT: 0x0010,
|
|
31
|
+
SET_INFORMATION: 0x0020,
|
|
32
|
+
QUERY_INFORMATION: 0x0040,
|
|
33
|
+
SET_THREAD_TOKEN: 0x0080,
|
|
34
|
+
IMPERSONATE: 0x0100,
|
|
35
|
+
DIRECT_IMPERSONATION: 0x0200,
|
|
36
|
+
SET_LIMITED_INFORMATION: 0x0400,
|
|
37
|
+
QUERY_LIMITED_INFORMATION: 0x0800,
|
|
38
|
+
ALL_ACCESS: 0x1fffff,
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Memory protection constants
|
|
42
|
+
* https://learn.microsoft.com/en-us/windows/win32/memory/memory-protection-constants
|
|
43
|
+
*/
|
|
44
|
+
export const MemoryProtection = {
|
|
45
|
+
NOACCESS: 0x01,
|
|
46
|
+
READONLY: 0x02,
|
|
47
|
+
READWRITE: 0x04,
|
|
48
|
+
WRITECOPY: 0x08,
|
|
49
|
+
EXECUTE: 0x10,
|
|
50
|
+
EXECUTE_READ: 0x20,
|
|
51
|
+
EXECUTE_READWRITE: 0x40,
|
|
52
|
+
EXECUTE_WRITECOPY: 0x80,
|
|
53
|
+
GUARD: 0x100,
|
|
54
|
+
NOCACHE: 0x200,
|
|
55
|
+
WRITECOMBINE: 0x400,
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Memory state constants
|
|
59
|
+
*/
|
|
60
|
+
export const MemoryState = {
|
|
61
|
+
COMMIT: 0x1000,
|
|
62
|
+
RESERVE: 0x2000,
|
|
63
|
+
FREE: 0x10000,
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Memory type constants
|
|
67
|
+
*/
|
|
68
|
+
export const MemoryType = {
|
|
69
|
+
PRIVATE: 0x20000,
|
|
70
|
+
MAPPED: 0x40000,
|
|
71
|
+
IMAGE: 0x1000000,
|
|
72
|
+
};
|
|
73
|
+
import koffi from 'koffi';
|
|
74
|
+
// Koffi struct for MEMORY_BASIC_INFORMATION (64-bit)
|
|
75
|
+
export const MEMORY_BASIC_INFORMATION = koffi.struct('MEMORY_BASIC_INFORMATION', {
|
|
76
|
+
BaseAddress: 'uint64',
|
|
77
|
+
AllocationBase: 'uint64',
|
|
78
|
+
AllocationProtect: 'uint32',
|
|
79
|
+
__PartitionId: 'uint16',
|
|
80
|
+
__pad: 'uint16',
|
|
81
|
+
RegionSize: 'uint64',
|
|
82
|
+
State: 'uint32',
|
|
83
|
+
Protect: 'uint32',
|
|
84
|
+
Type: 'uint32',
|
|
85
|
+
__pad2: 'uint32',
|
|
86
|
+
});
|
|
87
|
+
export const MBI_SIZE = koffi.sizeof(MEMORY_BASIC_INFORMATION);
|
|
88
|
+
/**
|
|
89
|
+
* CONTEXT flags for x64
|
|
90
|
+
* https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-context
|
|
91
|
+
*/
|
|
92
|
+
const CONTEXT_AMD64 = 0x00100000;
|
|
93
|
+
export const ContextFlags = {
|
|
94
|
+
AMD64: CONTEXT_AMD64,
|
|
95
|
+
CONTROL: CONTEXT_AMD64 | 0x01,
|
|
96
|
+
INTEGER: CONTEXT_AMD64 | 0x02,
|
|
97
|
+
SEGMENTS: CONTEXT_AMD64 | 0x04,
|
|
98
|
+
FLOATING_POINT: CONTEXT_AMD64 | 0x08,
|
|
99
|
+
DEBUG_REGISTERS: CONTEXT_AMD64 | 0x10,
|
|
100
|
+
FULL: CONTEXT_AMD64 | 0x01 | 0x02 | 0x08,
|
|
101
|
+
ALL: CONTEXT_AMD64 | 0x01 | 0x02 | 0x04 | 0x08 | 0x10,
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* M128A structure (128-bit register value)
|
|
105
|
+
* https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-m128a
|
|
106
|
+
*/
|
|
107
|
+
export const M128A = koffi.struct('M128A', {
|
|
108
|
+
Low: 'uint64',
|
|
109
|
+
High: 'int64',
|
|
110
|
+
});
|
|
111
|
+
/**
|
|
112
|
+
* CONTEXT structure for x64 (AMD64)
|
|
113
|
+
* https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-context
|
|
114
|
+
*/
|
|
115
|
+
export const CONTEXT = koffi.struct('CONTEXT', {
|
|
116
|
+
// Register parameter home addresses
|
|
117
|
+
P1Home: 'uint64',
|
|
118
|
+
P2Home: 'uint64',
|
|
119
|
+
P3Home: 'uint64',
|
|
120
|
+
P4Home: 'uint64',
|
|
121
|
+
P5Home: 'uint64',
|
|
122
|
+
P6Home: 'uint64',
|
|
123
|
+
// Control flags
|
|
124
|
+
ContextFlags: 'uint32',
|
|
125
|
+
MxCsr: 'uint32',
|
|
126
|
+
// Segment registers
|
|
127
|
+
SegCs: 'uint16',
|
|
128
|
+
SegDs: 'uint16',
|
|
129
|
+
SegEs: 'uint16',
|
|
130
|
+
SegFs: 'uint16',
|
|
131
|
+
SegGs: 'uint16',
|
|
132
|
+
SegSs: 'uint16',
|
|
133
|
+
// Flags
|
|
134
|
+
EFlags: 'uint32',
|
|
135
|
+
// Debug registers
|
|
136
|
+
Dr0: 'uint64',
|
|
137
|
+
Dr1: 'uint64',
|
|
138
|
+
Dr2: 'uint64',
|
|
139
|
+
Dr3: 'uint64',
|
|
140
|
+
Dr6: 'uint64',
|
|
141
|
+
Dr7: 'uint64',
|
|
142
|
+
// Integer registers
|
|
143
|
+
Rax: 'uint64',
|
|
144
|
+
Rcx: 'uint64',
|
|
145
|
+
Rdx: 'uint64',
|
|
146
|
+
Rbx: 'uint64',
|
|
147
|
+
Rsp: 'uint64',
|
|
148
|
+
Rbp: 'uint64',
|
|
149
|
+
Rsi: 'uint64',
|
|
150
|
+
Rdi: 'uint64',
|
|
151
|
+
R8: 'uint64',
|
|
152
|
+
R9: 'uint64',
|
|
153
|
+
R10: 'uint64',
|
|
154
|
+
R11: 'uint64',
|
|
155
|
+
R12: 'uint64',
|
|
156
|
+
R13: 'uint64',
|
|
157
|
+
R14: 'uint64',
|
|
158
|
+
R15: 'uint64',
|
|
159
|
+
// Program counter
|
|
160
|
+
Rip: 'uint64',
|
|
161
|
+
// Floating point / XMM save area (XMM_SAVE_AREA32 = 512 bytes)
|
|
162
|
+
FltSave: 'uint8[512]',
|
|
163
|
+
// Vector registers
|
|
164
|
+
VectorRegister: 'M128A[26]',
|
|
165
|
+
VectorControl: 'uint64',
|
|
166
|
+
// Special debug registers
|
|
167
|
+
DebugControl: 'uint64',
|
|
168
|
+
LastBranchToRip: 'uint64',
|
|
169
|
+
LastBranchFromRip: 'uint64',
|
|
170
|
+
LastExceptionToRip: 'uint64',
|
|
171
|
+
LastExceptionFromRip: 'uint64',
|
|
172
|
+
});
|
|
173
|
+
export const CONTEXT_SIZE = koffi.sizeof(CONTEXT);
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as D from 'win32-def';
|
|
2
|
+
export declare const Kernel32Impl: {
|
|
3
|
+
OpenProcess: (dwDesiredAccess: D.DWORD, bInheritHandle: D.BOOL, dwProcessId: D.DWORD) => D.HANDLE;
|
|
4
|
+
GetCurrentProcess: () => D.HANDLE;
|
|
5
|
+
GetCurrentProcessId: () => D.DWORD;
|
|
6
|
+
CloseHandle: (hObject: D.HANDLE) => D.BOOL;
|
|
7
|
+
ReadProcessMemory: (hProcess: D.HANDLE, lpBaseAddress: D.LPCVOID, lpBuffer: Buffer, nSize: D.SIZE_T, _lpNumberOfBytesRead: D.LPDWORD | null) => D.BOOL;
|
|
8
|
+
WriteProcessMemory: (hProcess: D.HANDLE, lpBaseAddress: D.LPCVOID, lpBuffer: Buffer, nSize: D.SIZE_T, _lpNumberOfBytesWritten: D.LPDWORD | null) => D.BOOL;
|
|
9
|
+
VirtualAlloc: (lpAddress: D.LPCVOID, dwSize: D.SIZE_T, flAllocationType: D.DWORD, flProtect: D.DWORD) => D.LPVOID;
|
|
10
|
+
VirtualAllocEx: (hProcess: D.HANDLE, lpAddress: D.LPCVOID, dwSize: D.SIZE_T, flAllocationType: D.DWORD, flProtect: D.DWORD) => D.LPVOID;
|
|
11
|
+
VirtualQuery: (lpAddress: D.LPCVOID, lpBuffer: Buffer, dwLength: D.SIZE_T) => D.SIZE_T;
|
|
12
|
+
VirtualQueryEx: (hProcess: D.HANDLE, lpAddress: D.LPCVOID, lpBuffer: Buffer, dwLength: D.SIZE_T) => D.SIZE_T;
|
|
13
|
+
OpenThread: (_dwDesiredAccess: D.DWORD, _bInheritHandle: D.BOOL, _dwThreadId: D.DWORD) => D.HANDLE;
|
|
14
|
+
GetCurrentThread: () => D.HANDLE;
|
|
15
|
+
GetCurrentThreadId: () => D.DWORD;
|
|
16
|
+
SuspendThread: (hThread: D.HANDLE) => D.DWORD;
|
|
17
|
+
ResumeThread: (hThread: D.HANDLE) => D.DWORD;
|
|
18
|
+
GetThreadContext: (_hThread: D.HANDLE, _lpContext: Buffer) => D.BOOL;
|
|
19
|
+
SetThreadContext: (_hThread: D.HANDLE, _lpContext: Buffer) => D.BOOL;
|
|
20
|
+
GetLastError: () => D.DWORD;
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=kernel32.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kernel32.d.ts","sourceRoot":"","sources":["../src/kernel32.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,WAAW,CAAC;AAQ/B,eAAO,MAAM,YAAY;mCAGJ,CAAC,CAAC,KAAK,kBACR,CAAC,CAAC,IAAI,eACT,CAAC,CAAC,KAAK,KACnB,CAAC,CAAC,MAAM;6BAGY,CAAC,CAAC,MAAM;+BACN,CAAC,CAAC,KAAK;2BACT,CAAC,CAAC,MAAM,KAAG,CAAC,CAAC,IAAI;kCAS5B,CAAC,CAAC,MAAM,iBACH,CAAC,CAAC,OAAO,YACd,MAAM,SACT,CAAC,CAAC,MAAM,wBACO,CAAC,CAAC,OAAO,GAAG,IAAI,KACrC,CAAC,CAAC,IAAI;mCA0BG,CAAC,CAAC,MAAM,iBACH,CAAC,CAAC,OAAO,YACd,MAAM,SACT,CAAC,CAAC,MAAM,2BACU,CAAC,CAAC,OAAO,GAAG,IAAI,KACxC,CAAC,CAAC,IAAI;8BA6BI,CAAC,CAAC,OAAO,UACZ,CAAC,CAAC,MAAM,oBACE,CAAC,CAAC,KAAK,aACd,CAAC,CAAC,KAAK,KACjB,CAAC,CAAC,MAAM;+BAUC,CAAC,CAAC,MAAM,aACP,CAAC,CAAC,OAAO,UACZ,CAAC,CAAC,MAAM,oBACE,CAAC,CAAC,KAAK,aACd,CAAC,CAAC,KAAK,KACjB,CAAC,CAAC,MAAM;8BAkCE,CAAC,CAAC,OAAO,YACV,MAAM,YACN,CAAC,CAAC,MAAM,KACjB,CAAC,CAAC,MAAM;+BAUC,CAAC,CAAC,MAAM,aACP,CAAC,CAAC,OAAO,YACV,MAAM,YACN,CAAC,CAAC,MAAM,KACjB,CAAC,CAAC,MAAM;mCAsCS,CAAC,CAAC,KAAK,mBACR,CAAC,CAAC,IAAI,eACV,CAAC,CAAC,KAAK,KACnB,CAAC,CAAC,MAAM;4BAGW,CAAC,CAAC,MAAM;8BACN,CAAC,CAAC,KAAK;6BACN,CAAC,CAAC,MAAM,KAAG,CAAC,CAAC,KAAK;4BASnB,CAAC,CAAC,MAAM,KAAG,CAAC,CAAC,KAAK;iCASb,CAAC,CAAC,MAAM,cAAc,MAAM,KAAG,CAAC,CAAC,IAAI;iCAGrC,CAAC,CAAC,MAAM,cAAc,MAAM,KAAG,CAAC,CAAC,IAAI;wBAGhD,CAAC,CAAC,KAAK;CAC1B,CAAC"}
|
package/dist/kernel32.js
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { kernel } from './os/kernel';
|
|
2
|
+
// Constants
|
|
3
|
+
const PSEUDO_HANDLE_PROCESS = 0xffffffffffffffffn; // -1
|
|
4
|
+
const PSEUDO_HANDLE_THREAD = 0xfffffffffffffffen; // -2
|
|
5
|
+
export const Kernel32Impl = {
|
|
6
|
+
// Process
|
|
7
|
+
OpenProcess: (dwDesiredAccess, bInheritHandle, dwProcessId) => {
|
|
8
|
+
return kernel.OpenProcess(dwDesiredAccess, !!bInheritHandle, dwProcessId);
|
|
9
|
+
},
|
|
10
|
+
GetCurrentProcess: () => PSEUDO_HANDLE_PROCESS,
|
|
11
|
+
GetCurrentProcessId: () => kernel.currentProcess.id,
|
|
12
|
+
CloseHandle: (hObject) => {
|
|
13
|
+
if (hObject === PSEUDO_HANDLE_PROCESS || hObject === PSEUDO_HANDLE_THREAD) {
|
|
14
|
+
return 1;
|
|
15
|
+
}
|
|
16
|
+
return kernel.CloseHandle(hObject) ? 1 : 0;
|
|
17
|
+
},
|
|
18
|
+
// Memory
|
|
19
|
+
ReadProcessMemory: (hProcess, lpBaseAddress, // bigint | number
|
|
20
|
+
lpBuffer, // LPVOID
|
|
21
|
+
nSize, // bigint | number
|
|
22
|
+
_lpNumberOfBytesRead) => {
|
|
23
|
+
let process;
|
|
24
|
+
if (hProcess === PSEUDO_HANDLE_PROCESS) {
|
|
25
|
+
process = kernel.currentProcess;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
const handleObj = kernel.getObjectFromHandle(hProcess);
|
|
29
|
+
if (handleObj && handleObj.type === 'Process') {
|
|
30
|
+
process = handleObj.object;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (!process)
|
|
34
|
+
return 0;
|
|
35
|
+
const addr = Number(lpBaseAddress);
|
|
36
|
+
const size = Number(nSize);
|
|
37
|
+
try {
|
|
38
|
+
const data = process.memory.read(addr, size);
|
|
39
|
+
data.copy(lpBuffer);
|
|
40
|
+
return 1;
|
|
41
|
+
}
|
|
42
|
+
catch (_e) {
|
|
43
|
+
return 0;
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
WriteProcessMemory: (hProcess, lpBaseAddress, lpBuffer, nSize, _lpNumberOfBytesWritten) => {
|
|
47
|
+
let process;
|
|
48
|
+
if (hProcess === PSEUDO_HANDLE_PROCESS) {
|
|
49
|
+
process = kernel.currentProcess;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
const handleObj = kernel.getObjectFromHandle(hProcess);
|
|
53
|
+
if (handleObj && handleObj.type === 'Process') {
|
|
54
|
+
process = handleObj.object;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (!process)
|
|
58
|
+
return 0;
|
|
59
|
+
const addr = Number(lpBaseAddress);
|
|
60
|
+
// Ensure we only write nSize bytes essentially
|
|
61
|
+
const dataToWrite = lpBuffer.subarray(0, Number(nSize));
|
|
62
|
+
try {
|
|
63
|
+
if (process.memory.write(addr, dataToWrite) > 0) {
|
|
64
|
+
return 1;
|
|
65
|
+
}
|
|
66
|
+
return 0;
|
|
67
|
+
}
|
|
68
|
+
catch (_e) {
|
|
69
|
+
return 0;
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
VirtualAlloc: (lpAddress, dwSize, flAllocationType, flProtect) => {
|
|
73
|
+
return Kernel32Impl.VirtualAllocEx(PSEUDO_HANDLE_PROCESS, lpAddress, dwSize, flAllocationType, flProtect);
|
|
74
|
+
},
|
|
75
|
+
VirtualAllocEx: (hProcess, lpAddress, dwSize, flAllocationType, flProtect) => {
|
|
76
|
+
let process;
|
|
77
|
+
if (hProcess === PSEUDO_HANDLE_PROCESS) {
|
|
78
|
+
process = kernel.currentProcess;
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
const handleObj = kernel.getObjectFromHandle(hProcess);
|
|
82
|
+
if (handleObj && handleObj.type === 'Process') {
|
|
83
|
+
process = handleObj.object;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (!process)
|
|
87
|
+
return 0n;
|
|
88
|
+
const addr = Number(lpAddress);
|
|
89
|
+
const size = Number(dwSize);
|
|
90
|
+
// We assume flAllocationType and flProtect match our internal constants or we pass them through
|
|
91
|
+
// Our MemoryManager uses constants from constants.ts which match Win32
|
|
92
|
+
try {
|
|
93
|
+
const allocatedAddr = process.memory.allocate(addr, size, flAllocationType, flProtect);
|
|
94
|
+
return BigInt(allocatedAddr);
|
|
95
|
+
}
|
|
96
|
+
catch (_e) {
|
|
97
|
+
return 0n;
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
VirtualQuery: (lpAddress, lpBuffer, // PMEMORY_BASIC_INFORMATION
|
|
101
|
+
dwLength) => {
|
|
102
|
+
// Queries CURRENT process
|
|
103
|
+
return Kernel32Impl.VirtualQueryEx(PSEUDO_HANDLE_PROCESS, lpAddress, lpBuffer, dwLength);
|
|
104
|
+
},
|
|
105
|
+
VirtualQueryEx: (hProcess, lpAddress, lpBuffer, dwLength) => {
|
|
106
|
+
let process;
|
|
107
|
+
if (hProcess === PSEUDO_HANDLE_PROCESS) {
|
|
108
|
+
process = kernel.currentProcess;
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
const handleObj = kernel.getObjectFromHandle(hProcess);
|
|
112
|
+
if (handleObj && handleObj.type === 'Process') {
|
|
113
|
+
process = handleObj.object;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (!process)
|
|
117
|
+
return 0n;
|
|
118
|
+
const addr = Number(lpAddress);
|
|
119
|
+
const info = process.memory.query(addr);
|
|
120
|
+
// Serialize info to lpBuffer
|
|
121
|
+
// BaseAddress (0)
|
|
122
|
+
lpBuffer.writeBigUInt64LE(BigInt(info.BaseAddress), 0);
|
|
123
|
+
// AllocationBase (8)
|
|
124
|
+
lpBuffer.writeBigUInt64LE(BigInt(info.AllocationBase), 8);
|
|
125
|
+
// AllocationProtect (16)
|
|
126
|
+
lpBuffer.writeUInt32LE(info.AllocationProtect, 16);
|
|
127
|
+
// RegionSize (24)
|
|
128
|
+
lpBuffer.writeBigUInt64LE(BigInt(info.RegionSize), 24);
|
|
129
|
+
// State (32)
|
|
130
|
+
lpBuffer.writeUInt32LE(info.State, 32);
|
|
131
|
+
// Protect (36)
|
|
132
|
+
lpBuffer.writeUInt32LE(info.Protect, 36);
|
|
133
|
+
// Type (40)
|
|
134
|
+
lpBuffer.writeUInt32LE(info.Type, 40);
|
|
135
|
+
return BigInt(dwLength);
|
|
136
|
+
},
|
|
137
|
+
// Thread
|
|
138
|
+
OpenThread: (_dwDesiredAccess, _bInheritHandle, _dwThreadId) => {
|
|
139
|
+
return 0x200n;
|
|
140
|
+
},
|
|
141
|
+
GetCurrentThread: () => PSEUDO_HANDLE_THREAD,
|
|
142
|
+
GetCurrentThreadId: () => 98765,
|
|
143
|
+
SuspendThread: (hThread) => {
|
|
144
|
+
if (hThread === PSEUDO_HANDLE_THREAD)
|
|
145
|
+
return 0;
|
|
146
|
+
const handleObj = kernel.getObjectFromHandle(hThread);
|
|
147
|
+
if (handleObj && handleObj.type === 'Thread') {
|
|
148
|
+
// return (handleObj.object as SimulatedThread).suspend();
|
|
149
|
+
return 0; // SimulatedThread import might be cyclic or tricky, simplified for now
|
|
150
|
+
}
|
|
151
|
+
return 0; // Fail
|
|
152
|
+
},
|
|
153
|
+
ResumeThread: (hThread) => {
|
|
154
|
+
if (hThread === PSEUDO_HANDLE_THREAD)
|
|
155
|
+
return 0;
|
|
156
|
+
const handleObj = kernel.getObjectFromHandle(hThread);
|
|
157
|
+
if (handleObj && handleObj.type === 'Thread') {
|
|
158
|
+
// return (handleObj.object as SimulatedThread).resume();
|
|
159
|
+
return 0;
|
|
160
|
+
}
|
|
161
|
+
return 0;
|
|
162
|
+
},
|
|
163
|
+
GetThreadContext: (_hThread, _lpContext) => {
|
|
164
|
+
return 0;
|
|
165
|
+
},
|
|
166
|
+
SetThreadContext: (_hThread, _lpContext) => {
|
|
167
|
+
return 1;
|
|
168
|
+
},
|
|
169
|
+
GetLastError: () => 0,
|
|
170
|
+
};
|
package/dist/logger.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,GAAG,uCAAgC,CAAC"}
|
package/dist/logger.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as D from 'win32-def';
|
|
2
|
+
export interface ISimulatedObject {
|
|
3
|
+
id: number;
|
|
4
|
+
}
|
|
5
|
+
export interface HandleObject {
|
|
6
|
+
type: 'Process' | 'Thread' | 'File' | 'Event' | 'Unknown';
|
|
7
|
+
object: ISimulatedObject;
|
|
8
|
+
accessMask: number;
|
|
9
|
+
}
|
|
10
|
+
export declare class HandleTable {
|
|
11
|
+
private handles;
|
|
12
|
+
private nextHandleValue;
|
|
13
|
+
createHandle(object: ISimulatedObject, type: HandleObject['type'], accessMask: number): D.HANDLE;
|
|
14
|
+
getObject(handle: D.HANDLE): HandleObject | undefined;
|
|
15
|
+
closeHandle(handle: D.HANDLE): boolean;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=handles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handles.d.ts","sourceRoot":"","sources":["../../src/os/handles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,WAAW,CAAC;AAE/B,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;IAC1D,MAAM,EAAE,gBAAgB,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,eAAe,CAAM;IAE7B,YAAY,CACV,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,EAC1B,UAAU,EAAE,MAAM,GACjB,CAAC,CAAC,MAAM;IAeX,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,GAAG,YAAY,GAAG,SAAS;IAIrD,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,GAAG,OAAO;CAGvC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export class HandleTable {
|
|
2
|
+
handles = new Map();
|
|
3
|
+
nextHandleValue = 4n; // Windows handles are often multiples of 4
|
|
4
|
+
createHandle(object, type, accessMask) {
|
|
5
|
+
const handleValue = this.nextHandleValue;
|
|
6
|
+
this.nextHandleValue += 4n;
|
|
7
|
+
// Simulate handle reuse? For now, just increment.
|
|
8
|
+
this.handles.set(handleValue, {
|
|
9
|
+
type,
|
|
10
|
+
object,
|
|
11
|
+
accessMask,
|
|
12
|
+
});
|
|
13
|
+
return handleValue;
|
|
14
|
+
}
|
|
15
|
+
getObject(handle) {
|
|
16
|
+
return this.handles.get(BigInt(handle));
|
|
17
|
+
}
|
|
18
|
+
closeHandle(handle) {
|
|
19
|
+
return this.handles.delete(BigInt(handle));
|
|
20
|
+
}
|
|
21
|
+
}
|