-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcapstone.ts
2218 lines (2122 loc) · 91.5 KB
/
capstone.ts
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
import Module from './libcapstone';
import { Memory } from './memory';
import {
// ARM64 architecture
type cs_arm64_op,
ARM64,
cs_arm64,
// ARM architecture
type cs_arm_op,
ARM,
cs_arm,
// BPF architecture
type cs_bpf_op,
BPF,
cs_bpf,
// EVM architecture
EVM,
cs_evm,
// M680X architecture
type cs_m680x_op,
M680X,
cs_m680x,
// M68K architecture
type cs_m68k_op,
M68K,
cs_m68k,
// MIPS architecture
type cs_mips_op,
MIPS,
cs_mips,
// MOS65XX architecture
type cs_mos65xx_op,
MOS65XX,
cs_mos65xx,
// PPC architecture
type cs_ppc_op,
PPC,
cs_ppc,
// RISCV architecture
type cs_riscv_op,
RISCV,
cs_riscv,
// SH architecture
type cs_sh_op,
SH,
cs_sh,
// SPARC architecture
type cs_sparc_op,
SPARC,
cs_sparc,
// TMS320C64X architecture
type cs_tms320c64x_op,
TMS320C64X,
cs_tms320c64x,
// TRICORE architecture
type cs_tricore_op,
TRICORE,
cs_tricore,
// WASM architecture
type cs_wasm_op,
WASM,
cs_wasm,
// X86 architecture
type cs_x86_op,
X86,
cs_x86,
// XCORE architecture
type cs_xcore_op,
XCORE,
cs_xcore,
// SYSZ architecture
type cs_sysz_op,
SYSZ,
cs_sysz,
} from './arch';
const Wrapper: wasm_module = Module() as wasm_module;
type cs_err = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14; // All type of errors encountered by Capstone API. These are values returned by cs_errno()
type cs_arch = number; // Architecture type
type cs_mode = number; // Mode type
type cs_opt_type = number; // Runtime option for the disassembled engine
type cs_opt_value = number; // Runtime option value (associated with option type above)
type cs_group_type = number; // Common instruction groups - to be consistent across all architectures.
type cs_op_type = number; // Common instruction operand types - to be consistent across all architectures
type cs_ac_type = number; // Common instruction operand access types - to be consistent across all architectures. It is possible to combine access types, for example: CS_AC_READ | CS_AC_WRITE
type cs_regs = number[]; // Type of array to keep the list of registers
type csh = number; // Handle using with all API
type cs_skipdata_cb_t = (
code: number,
code_size: number,
offset: number,
user_data: any,
) => number; // User-defined callback function for SKIPDATA option
type pointer_t<T extends any> = number; // Points to a specific memory address
type wasm_arg = 'number' | 'string' | 'array' | 'boolean' | 'pointer' | null; // types of arguments for the C function.
type wasm_t = 'i8' | 'i16' | 'i32' | 'i64' | 'float' | 'double' | 'i8*' | '*'; // An LLVM IR type as a string
// Module object with attributes that Emscripten-generated code calls at various points in its execution.
interface wasm_module {
HEAP8: Int8Array; // View for 8-bit signed memory.
HEAPU8: Uint8Array; // View for 8-bit unsigned memory.
HEAP16: Int16Array; // View for 16-bit signed memory.
HEAPU16: Uint16Array; // View for 16-bit unsigned memory.
HEAP32: Int32Array; // View for 32-bit signed memory.
HEAPU32: Uint32Array; // View for 32-bit unsigned memory.
HEAPF32: Float32Array; // View for 32-bit float memory.
HEAPF64: Float64Array; // View for 8-bit float memory.
_cs_free: (insn: pointer_t<cs_insn>, count: number) => void; // Free memory allocated by _cs_malloc() or disasm()
_cs_malloc: (handle: csh) => pointer_t<cs_insn>; // Allocate memory for 1 instruction to be used by disasm_iter()
_malloc: (size: number) => pointer_t<any>; // Allocates a block of memory on the heap, must be paired with free(), or heap memory will leak! (use Memory.malloc()).
_free: (pointer: pointer_t<any>) => void; // Free allocated memory (use Memory.free()).
_cs_reg_write: (
handle: csh,
insn: pointer_t<cs_insn>,
reg_id: number,
) => number; // Check if a disassembled instruction IMPLICITLY modified a particular register.
_cs_reg_read: (
handle: csh,
insn: pointer_t<cs_insn>,
reg_id: number,
) => number; // Check if a disassembled instruction IMPLICITLY used a particular register.
_cs_insn_group: (
handle: csh,
insn: pointer_t<cs_insn>,
group_id: number,
) => number; // Check if a disassembled instruction belong to a particular group.
_cs_regs_access: (
handle: csh,
insn: pointer_t<cs_insn>,
regs_read: pointer_t<cs_regs>,
regs_read_count: pointer_t<number>,
regs_write: pointer_t<cs_regs>,
regs_write_count: pointer_t<number>,
) => cs_err; // Retrieve all the registers accessed by an instruction, either explicitly or implicitly.
_cs_op_count: (
handle: csh,
insn: pointer_t<cs_insn>,
op_type: number,
) => number; // Count the number of operands of a given type.
_cs_op_index: (
handle: csh,
insn: pointer_t<cs_insn>,
op_type: number,
position: number,
) => number; // Retrieve the position of operand of given type in <arch>.operands[] array.
_cs_insn_offset: (insns: pointer_t<cs_insn[]>, post: number) => number; // Calculate the offset of a disassembled instruction in its buffer, given its position in its array of disassembled insn.
_cs_detail_buffer: (insn: pointer_t<cs_insn>) => pointer_t<Uint8Array>; // Gets the raw buffer of the specified insns cs_detail.
_cs_insn_buffer: (insn: pointer_t<cs_insn>) => pointer_t<Uint8Array>; // Gets the raw buffer of the cs_insn
_x86_rel_addr: (insn: pointer_t<cs_insn>) => number; // Calculate relative address for X86-64, given cs_insn structure
ccall: (
ident: string, // name of C function
returnType: wasm_arg, // return type
argTypes: wasm_arg[], // argument types
args: any[], // arguments
opts?: {
async: boolean; // If true, implies that the ccall will perform an async operation. This assumes you are build with asyncify support.
},
) => any; // Call a compiled C function from JavaScript.
setValue: (pointer: number, value: any, type: wasm_t) => void; // Sets a value at a specific memory address at run-time (use Memory.write()).
getValue: (pointer: number, type: wasm_t) => any; // Gets a value at a specific memory address at run-time (use Memory.read()).
UTF8ToString: (pointer: number, maxBytesToRead?: number) => string; // Given a pointer pointer_t to a null-terminated UTF8-encoded string in the Emscripten HEAP, returns a copy of that string as a JavaScript String object.
addFunction: (func: Function, sig: string) => any; // You can use addFunction to return an integer value that represents a function pointer
writeArrayToMemory: (
array: number[] | Uint8Array | Buffer,
buffer: pointer_t<number[] | Uint8Array | Buffer>,
) => void; // Writes an array to a specified address in the heap. Note that memory should to be allocated for the array before it is written.
}
// Detail information of disassembled instruction
interface cs_insn {
id: number; // Instruction ID (basically a numeric ID for the instruction mnemonic) Find the instruction id in the 'ARCH_insn' enum in the header file of corresponding architecture, such as 'arm_insn' in arm.h for ARM, 'x86_insn' in x86.h for X86, etc... This information is available even when CS_OPT_DETAIL = CS_OPT_OFF NOTE: in Skipdata mode, "data" instruction has 0 for this id field.
address: number; // Address (EIP) of this instruction This information is available even when CS_OPT_DETAIL = CS_OPT_OFF
size: number; // Size of this instruction This information is available even when CS_OPT_DETAIL = CS_OPT_OFF
mnemonic: string; // Ascii text of instruction mnemonic This information is available even when CS_OPT_DETAIL = CS_OPT_OFF
op_str: string; // Ascii text of instruction operands This information is available even when CS_OPT_DETAIL = CS_OPT_OFF
bytes: Uint8Array; // Machine bytes of this instruction, with number of bytes indicated by @size above This information is available even when CS_OPT_DETAIL = CS_OPT_OFF
detail?: cs_detail; // cs_detail object
buffer?: Uint8Array; // The raw detail buffer, this will only be present if CS.OPT_BUFFER is on.
}
// cs_detail object. NOTE: detail object is only valid when both requirements below are met: (1) CS_OP_DETAIL = CS_OPT_ON (2) Engine is not in Skipdata mode (CS_OP_SKIPDATA option set to CS_OPT_ON)
interface cs_detail {
[index: string]: any;
regs_read: cs_regs; // list of implicit registers read by this insn
regs_read_count: number; // number of implicit registers read by this insn
regs_write: cs_regs; // list of implicit registers modified by this insn
regs_write_count: number; // number of implicit registers modified by this insn
groups: number[]; // list of group this instruction belong to
groups_count: number; // number of groups this insn belongs to
writeback: boolean; // Instruction has writeback operands.
buffer?: Uint8Array; // The raw detail buffer, this will only be present if CS.OPT_BUFFER is on.
x86?: cs_x86; // X86 architecture, including 16-bit, 32-bit & 64-bit mode
arm?: cs_arm; // ARM64 architecture (aka AArch64)
arm64?: cs_arm64; // ARM architecture (including Thumb/Thumb2)
m68k?: cs_m68k; // M68K architecture
mips?: cs_mips; // MIPS architecture
ppc?: cs_ppc; // PowerPC architecture
sparc?: cs_sparc; // Sparc architecture
sysz?: cs_sysz; // SystemZ architecture
xcore?: cs_xcore; // XCore architecture
tms320c64x?: cs_tms320c64x; // TMS320C64x architecture
m680x?: cs_m680x; // M680X architecture
evm?: cs_evm; // Ethereum architecture
mos65xx?: cs_mos65xx; //MOS65XX architecture (including MOS6502)
wasm?: cs_wasm; // Web Assembly architecture
bpf?: cs_bpf; // Berkeley Packet Filter architecture (including eBPF)
riscv?: cs_riscv; // RISCV architecture
sh?: cs_sh; // SH architecture
tricore?: cs_tricore; // TriCore architecture
// alpha?: cs_alpha; // Alpha architecture
// hppa?: cs_hppa; // HPPA architecture
}
// User-customized setup for SKIPDATA option
interface cs_opt_skipdata {
mnemonic: string | null; // Capstone considers data to skip as special "instructions", User can specify the string for this instruction's "mnemonic" here (default = ".byte").
callback: cs_skipdata_cb_t | null; // User-defined callback function to be called when Capstone hits data (default = null).
user_data: object; // User-defined data to be passed to callback function.
}
// fmt() options
interface cs_opt_fmt {
hex_comment?: boolean; // Specifies if the output should include decimal comments for hexadecimal imm
colors?: boolean; // Specifies if the output should include coloring
bytes?: boolean; // Specifies if the formatted string should have the instructions bytes.
address?: boolean; // Specifies if the formatted string should include the instructions address.
ASCII?: boolean; // Specifies if the formatted string should include the bytes ASCII representation.
}
// Customize mnemonic for instructions with alternative name.
// To reset existing customized instruction to its default mnemonic,
// call option(CS.OPT_MNEMONIC) again with the same id and null value
interface cs_opt_mnem {
id: number; // ID of instruction to be customized obtained from the cs_insn object.
mnemonic: string | null; // Customized instruction mnemonic(or null).
}
namespace CS {
// Return codes
export const ERR_OK: cs_err = 0; // No error: everything was fine
export const ERR_MEM: cs_err = 1; // Out-Of-Memory error: cs_open(), cs_disasm(), cs_disasm_iter()
export const ERR_ARCH: cs_err = 2; // Unsupported architecture: cs_open()
export const ERR_HANDLE: cs_err = 3; // Invalid handle: cs_op_count(), cs_op_index()
export const ERR_CSH: cs_err = 4; // Invalid csh argument: cs_close(), cs_errno(), cs_option()
export const ERR_MODE: cs_err = 5; // Invalid/unsupported mode: cs_open()
export const ERR_OPTION: cs_err = 6; // Invalid/unsupported option: cs_option()
export const ERR_DETAIL: cs_err = 7; // Information is unavailable because detail option is OFF
export const ERR_MEMSETUP: cs_err = 8; // Dynamic memory management uninitialized (see OPT_MEM)
export const ERR_VERSION: cs_err = 9; // Unsupported version (bindings)
export const ERR_DIET: cs_err = 10; // Access irrelevant data in "diet" engine
export const ERR_SKIPDATA: cs_err = 11; // Access irrelevant data for "data" instruction in SKIPDATA mode
export const ERR_X86_ATT: cs_err = 12; // X86 AT&T syntax is unsupported (opt-out at compile time)
export const ERR_X86_INTEL: cs_err = 13; // X86 Intel syntax is unsupported (opt-out at compile time)
export const ERR_X86_MASM: cs_err = 14; // X86 Intel syntax is unsupported (opt-out at compile time)
// Architectures
export const ARCH_ARM: cs_arch = 0; // ARM architecture (including Thumb, Thumb-2)
export const ARCH_ARM64: cs_arch = 1; // ARM-64, also called AArch64
export const ARCH_AARCH64: cs_arch = 1; // AArch-64, also called ARM-64
export const ARCH_MIPS: cs_arch = 2; // Mips architecture
export const ARCH_X86: cs_arch = 3; // X86 architecture (including x86 & x86-64)
export const ARCH_PPC: cs_arch = 4; // PowerPC architecture
export const ARCH_SPARC: cs_arch = 5; // Sparc architecture
export const ARCH_SYSZ: cs_arch = 6; // SystemZ architecture
export const ARCH_XCORE: cs_arch = 7; // XCore architecture
export const ARCH_M68K: cs_arch = 8; // 68K architecture
export const ARCH_TMS320C64X: cs_arch = 9; // TMS320C64x architecture
export const ARCH_M680X: cs_arch = 10; // 680X architecture
export const ARCH_EVM: cs_arch = 11; // Ethereum architecture
export const ARCH_MOS65XX: cs_arch = 12; // MOS65XX architecture (including MOS6502)
export const ARCH_WASM: cs_arch = 13; // WebAssembly architecture
export const ARCH_BPF: cs_arch = 14; // Berkeley Packet Filter architecture (including eBPF)
export const ARCH_RISCV: cs_arch = 15; // RISCV architecture
export const ARCH_SH: cs_arch = 16; // SH architecture
export const ARCH_TRICORE: cs_arch = 17; // TriCore architecture
// export const ARCH_ALPHA = 18; // Alpha architecture
// export const ARCH_HPPA = 19; // HPPA architecture
export const ARCH_MAX: cs_arch = 18; // The maximum architecture value.
export const ARCH_ALL: cs_arch = 0xffff; // Represents a mask that includes all architecture values.
// Modes
export const MODE_LITTLE_ENDIAN: cs_mode = 0; // little-endian mode (default mode)
export const MODE_ARM: cs_mode = 0; // 32-bit ARM
export const MODE_16: cs_mode = 1 << 1; // 16-bit mode (X86)
export const MODE_32: cs_mode = 1 << 2; // 32-bit mode (X86)
export const MODE_64: cs_mode = 1 << 3; // 64-bit mode (X86, PPC)
export const MODE_THUMB: cs_mode = 1 << 4; // ARM's Thumb mode, including Thumb-2
export const MODE_MCLASS: cs_mode = 1 << 5; // ARM's Cortex-M series
export const MODE_V8: cs_mode = 1 << 6; // ARMv8 A32 encodings for ARM
export const MODE_MICRO: cs_mode = 1 << 4; // MicroMips mode (MIPS)
export const MODE_MIPS3: cs_mode = 1 << 5; // Mips III ISA
export const MODE_MIPS32R6: cs_mode = 1 << 6; // Mips32r6 ISA
export const MODE_MIPS2: cs_mode = 1 << 7; // Mips II ISA
export const MODE_V9: cs_mode = 1 << 4; // SparcV9 mode (Sparc)
export const MODE_QPX: cs_mode = 1 << 4; // Quad Processing eXtensions mode (PPC)
export const MODE_SPE: cs_mode = 1 << 5; // Signal Processing Engine mode (PPC)
export const MODE_BOOKE: cs_mode = 1 << 6; // Book-E mode (PPC)
export const MODE_PS: cs_mode = 1 << 7; // Paired-singles mode (PPC)
export const MODE_M68K_000: cs_mode = 1 << 1; // M68K 68000 mode
export const MODE_M68K_010: cs_mode = 1 << 2; // M68K 68010 mode
export const MODE_M68K_020: cs_mode = 1 << 3; // M68K 68020 mode
export const MODE_M68K_030: cs_mode = 1 << 4; // M68K 68030 mode
export const MODE_M68K_040: cs_mode = 1 << 5; // M68K 68040 mode
export const MODE_M68K_060: cs_mode = 1 << 6; // M68K 68060 mode
export const MODE_BIG_ENDIAN: cs_mode = 1 << 31; // big-endian mode
export const MODE_MIPS32: cs_mode = MODE_32; // Mips32 ISA (Mips)
export const MODE_MIPS64: cs_mode = MODE_64; // Mips64 ISA (Mips)
export const MODE_M680X_6301: cs_mode = 1 << 1; // M680X Hitachi 6301,6303 mode
export const MODE_M680X_6309: cs_mode = 1 << 2; // M680X Hitachi 6309 mode
export const MODE_M680X_6800: cs_mode = 1 << 3; // M680X Motorola 6800,6802 mode
export const MODE_M680X_6801: cs_mode = 1 << 4; // M680X Motorola 6801,6803 mode
export const MODE_M680X_6805: cs_mode = 1 << 5; // M680X Motorola/Freescale 6805 mode
export const MODE_M680X_6808: cs_mode = 1 << 6; // M680X Motorola/Freescale/NXP 68HC08 mode
export const MODE_M680X_6809: cs_mode = 1 << 7; // M680X Motorola 6809 mode
export const MODE_M680X_6811: cs_mode = 1 << 8; // M680X Motorola/Freescale/NXP 68HC11 mode
export const MODE_M680X_CPU12: cs_mode = 1 << 9; // M680X Motorola/Freescale/NXP CPU12
export const MODE_M680X_HCS08: cs_mode = 1 << 10; // M680X Freescale/NXP HCS08 mode
export const MODE_BPF_CLASSIC: cs_mode = 0; // Classic BPF mode (default)
export const MODE_BPF_EXTENDED: cs_mode = 1 << 0; // Extended BPF mode
export const MODE_RISCV32: cs_mode = 1 << 0; // RISCV RV32G
export const MODE_RISCV64: cs_mode = 1 << 1; // RISCV RV64G
export const MODE_RISCVC: cs_mode = 1 << 2; // RISCV compressed instructure mode
export const MODE_MOS65XX_6502: cs_mode = 1 << 1; // MOS65XXX MOS 6502
export const MODE_MOS65XX_65C02: cs_mode = 1 << 2; // MOS65XXX WDC 65c02
export const MODE_MOS65XX_W65C02: cs_mode = 1 << 3; // MOS65XXX WDC W65c02
export const MODE_MOS65XX_65816: cs_mode = 1 << 4; // MOS65XXX WDC 65816, 8-bit m/x
export const MODE_MOS65XX_65816_LONG_M: cs_mode = 1 << 5; // MOS65XXX WDC 65816, 16-bit m, 8-bit x
export const MODE_MOS65XX_65816_LONG_X: cs_mode = 1 << 6; // MOS65XXX WDC 65816, 8-bit m, 16-bit x
export const MODE_MOS65XX_65816_LONG_MX: cs_mode =
MODE_MOS65XX_65816_LONG_M | MODE_MOS65XX_65816_LONG_X;
export const MODE_SH2: cs_mode = 1 << 1; // SH2
export const MODE_SH2A: cs_mode = 1 << 2; // SH2A
export const MODE_SH3: cs_mode = 1 << 3; // SH3
export const MODE_SH4: cs_mode = 1 << 4; // SH4
export const MODE_SH4A: cs_mode = 1 << 5; // SH4A
export const MODE_SHFPU: cs_mode = 1 << 6; // w/ FPU
export const MODE_SHDSP: cs_mode = 1 << 7; // w/ DSP
export const MODE_TRICORE_110: cs_mode = 1 << 1; // Tricore 1.1
export const MODE_TRICORE_120: cs_mode = 1 << 2; // Tricore 1.2
export const MODE_TRICORE_130: cs_mode = 1 << 3; // Tricore 1.3
export const MODE_TRICORE_131: cs_mode = 1 << 4; // Tricore 1.3.1
export const MODE_TRICORE_160: cs_mode = 1 << 5; // Tricore 1.6
export const MODE_TRICORE_161: cs_mode = 1 << 6; // Tricore 1.6.1
export const MODE_TRICORE_162: cs_mode = 1 << 7; // Tricore 1.6.2
// export const MODE_TRICORE_162 = 1 << 7; // Tricore 1.6.2
// export const MODE_HPPA_11 = 1 << 1; // HPPA 1.1
// export const MODE_HPPA_20 = 1 << 2; // HPPA 2.0
// export const MODE_HPPA_20W = CS.MODE_HPPA_20 | (1 << 3); // HPPA 2.0 wide
// Runtime option for the disassembled engine
export const OPT_INVALID: cs_opt_type = 0; // No option specified
export const OPT_SYNTAX: cs_opt_type = 1; // Intel X86 asm syntax (CS_ARCH_X86 arch Assembly output syntax)
export const OPT_DETAIL: cs_opt_type = 2; // Break down instruction structure into details
export const OPT_MODE: cs_opt_type = 3; // Change engine's mode at run-time
export const OPT_MEM: cs_opt_type = 4; // Change engine's mode at run-time
export const OPT_SKIPDATA: cs_opt_type = 5; // Skip data when disassembling
export const OPT_SKIPDATA_SETUP: cs_opt_type = 6; // Setup user-defined function for SKIPDATA option
export const OPT_MNEMONIC: cs_opt_type = 7; // Customize instruction mnemonic
export const OPT_UNSIGNED: cs_opt_type = 8; // print immediate operands in unsigned form
export const OPT_NO_BRANCH_OFFSET: cs_opt_type = 9; // ARM, prints branch immediates without offset.
export const OPT_BUFFER: cs_opt_type = 10; // Adds the raw buffer to the insn and detail object.
// Capstone option value
export const OPT_OFF: cs_opt_value = 0; // Turn OFF an option - default option of CS_OPT_DETAIL
export const OPT_ON: cs_opt_value = 3; // Turn ON an option (CS_OPT_DETAIL)
// export const OPT_DETAIL_REAL: cs_opt_value = 1 << 1; // If enabled, always sets the real instruction detail. Even if the instruction is an alias.
// Capstone syntax value
export const OPT_SYNTAX_DEFAULT: cs_opt_value = 0; // Default assembly syntax of all platforms (CS_OPT_SYNTAX)
export const OPT_SYNTAX_INTEL: cs_opt_value = 1; // Intel X86 asm syntax - default syntax on X86 (CS_OPT_SYNTAX, CS_ARCH_X86)
export const OPT_SYNTAX_ATT: cs_opt_value = 2; // ATT asm syntax (CS_OPT_SYNTAX, CS_ARCH_X86)
export const OPT_SYNTAX_NOREGNAME: cs_opt_value = 3; // Asm syntax prints register name with only number - (CS_OPT_SYNTAX, CS_ARCH_PPC, CS_ARCH_ARM)
export const OPT_SYNTAX_MASM: cs_opt_value = 4; // X86 Intel Masm syntax (CS_OPT_SYNTAX).
export const OPT_SYNTAX_MOTOROLA: cs_opt_value = 5; // MOS65XX use $ as hex prefix.
// export const OPT_SYNTAX_CS_REG_ALIAS = 1 << 7; // Prints common register alias which are not defined in LLVM (ARM: r9 = sb etc.)
// export const OPT_SYNTAX_PERCENT = 1 << 8; // Prints the % in front of PPC registers.
// Common instruction groups - to be consistent across all architectures.
export const GRP_INVALID: cs_group_type = 0; // uninitialized/invalid group.
export const GRP_JUMP: cs_group_type = 1; // all jump instructions (conditional+direct+indirect jumps)
export const GRP_CALL: cs_group_type = 2; // all call instructions
export const GRP_RET: cs_group_type = 3; // all return instructions
export const GRP_INT: cs_group_type = 4; // all interrupt instructions (int+syscall)
export const GRP_IRET: cs_group_type = 5; // all interrupt return instructions
export const GRP_PRIVILEGE: cs_group_type = 6; // all privileged instructions
export const GRP_BRANCH_RELATIVE: cs_group_type = 7; // all relative branching instructions
// Common instruction operand types - to be consistent across all architectures.
export const OP_INVALID: cs_op_type = 0; // Uninitialized/invalid operand.
export const OP_REG: cs_op_type = 1; // Register operand.
export const OP_IMM: cs_op_type = 2; // Immediate operand.
export const OP_MEM: cs_op_type = 0x80; // Memory operand.
export const OP_FP: cs_op_type = 3; // Floating-Point operand.
// Common instruction operand access types - to be consistent across all architectures. It is possible to combine access types, for example: CS_AC_READ | CS_AC_WRITE
export const AC_INVALID: cs_ac_type = 0; // Uninitialized/invalid access type.
export const AC_READ: cs_ac_type = 1 << 0; // Operand read from memory or register.
export const AC_WRITE: cs_ac_type = 1 << 1; // Operand written to memory or register.
// query id for cs_support()
export const SUPPORT_DIET = ARCH_ALL + 1;
export const SUPPORT_X86_REDUCE = ARCH_ALL + 2;
// Manifest Constants
export const MNEMONIC_SIZE = 32;
export const INSN_SIZE = 240;
export const DETAIL_SIZE = 1864;
export const MAX_IMPL_W_REGS = 20;
export const MAX_IMPL_R_REGS = 20;
export const MAX_NUM_GROUPS = 8;
/**
* Retrieves the offset relative to the start of the buffer where the instruction resides.
*
* NOTE: this assumes position is (>=1)
* @param insns - The instructions to analyze.
* @param position - The index of the specific insn.
* @returns The offset of the instruction relative to the buffer.
*/
export function INSN_OFFSET(insns: cs_insn[], position: number): number {
const base: number = insns[0].address;
const positional: number = insns[position - 1].address;
return positional - base;
}
export class CAPSTONE {
private arch: cs_arch; // The chosen architecture for this instance(cannot be changed)
private mode: cs_mode; // The mode associated with the chooses arch(can be changed via CS.OPT_MODE)
private handle_ptr: pointer_t<csh>; // The address of the cash handle
private arch_info: { instance: any; name: string }; // Decides what architecture specific info will be present in cs_detail
private opt_buffer: boolean = false; // Option toggle for CS.OPT_BUFFER
/**
* Create a new instance of the Capstone disassembly engine.
*
* @param arch - The architecture type.
* @param mode - The mode type.
*/
constructor(arch: cs_arch, mode: cs_mode) {
this.arch = arch;
this.mode = mode;
this.handle_ptr = 0;
this.open();
this.arch_info = this.init(arch);
}
/**
* Return the Capstone library version as a string.
*
* @public
* @returns The Capstone library version as a string in the format "major.minor".
*/
public version(): string {
const major_ptr: number = Memory.malloc(4);
const minor_ptr: number = Memory.malloc(4);
Wrapper.ccall(
'cs_version',
'number',
['pointer', 'pointer'],
[major_ptr, minor_ptr],
);
const major: number = Memory.read(major_ptr, 'i32');
const minor: number = Memory.read(minor_ptr, 'i32');
Memory.free(major_ptr);
Memory.free(minor_ptr);
return `${major}.${minor}`;
}
/**
* Check if Capstone supports a specific query.
*
* @public
* @param query - The query ID to check.
* @returns A boolean indicating whether Capstone supports the given query.
*/
public support(query: number): boolean {
var ret: boolean = Wrapper.ccall(
'cs_support',
'number',
['number'],
[query],
);
return Boolean(ret);
}
/**
* Get the error message string for a given error code.
*
* @public
* @param code - The error code.
* @returns The error message string corresponding to the given error code.
*/
public strerror(code: number): string {
return Wrapper.ccall('cs_strerror', 'string', ['number'], [code]);
}
/**
* Get the error code for the most recent Capstone error that occurred with the given handle.
*
* @public
* @param handle - The handle for which to get the error code.
* @returns The error code for the most recent Capstone error.
*/
public errno(handle: csh): cs_err {
return Wrapper.ccall('cs_errno', 'number', ['pointer'], [handle]);
}
private init(arch: cs_arch): { instance: Function; name: string } {
const arch_map: { [key: number]: { instance: any; name: string } } = {
[CS.ARCH_ARM]: { instance: cs_arm, name: 'arm' },
[CS.ARCH_ARM64]: { instance: cs_arm64, name: 'arm64' },
[CS.ARCH_AARCH64]: { instance: cs_arm64, name: 'arm64' },
[CS.ARCH_MIPS]: { instance: cs_mips, name: 'mips' },
[CS.ARCH_X86]: { instance: cs_x86, name: 'x86' },
[CS.ARCH_PPC]: { instance: cs_ppc, name: 'ppc' },
[CS.ARCH_SPARC]: { instance: cs_sparc, name: 'sparc' },
[CS.ARCH_SYSZ]: { instance: cs_sysz, name: 'sysz' },
[CS.ARCH_XCORE]: { instance: cs_xcore, name: 'xcore' },
[CS.ARCH_TMS320C64X]: { instance: cs_tms320c64x, name: 'tms320c64x' },
[CS.ARCH_M680X]: { instance: cs_m680x, name: 'm680x' },
[CS.ARCH_M68K]: { instance: cs_m68k, name: 'm68k' },
[CS.ARCH_EVM]: { instance: cs_evm, name: 'evm' },
[CS.ARCH_MOS65XX]: { instance: cs_mos65xx, name: 'mos65xx' },
[CS.ARCH_WASM]: { instance: cs_wasm, name: 'wasm' },
[CS.ARCH_BPF]: { instance: cs_bpf, name: 'bpf' },
[CS.ARCH_RISCV]: { instance: cs_riscv, name: 'riscv' },
[CS.ARCH_SH]: { instance: cs_sh, name: 'sh' },
[CS.ARCH_TRICORE]: { instance: cs_tricore, name: 'tricore' },
};
return arch_map[arch];
}
/**
* Handler to parse the cs_opt_skipdata obj
*
* @private
* @param skipdata - User-customized setup for SKIPDATA option
* @returns The pointer to the cs_opt_skipdata struct
*/
private skipdata_cb(setup: any): number {
const { mnemonic, callback, user_data } = setup;
const skipdata_struct: pointer_t<cs_opt_skipdata> = Memory.malloc(24);
typeof mnemonic === 'string' &&
Memory.write(skipdata_struct, mnemonic, 'char*');
const callback_ptr: pointer_t<Function> = skipdata_struct + 8;
const user_data_ptr: pointer_t<any> = skipdata_struct + 16;
if (typeof callback === 'function') {
const cb_ptr = Wrapper.addFunction(function (
code_ptr: any,
code_size: any,
offset: any,
user_data: any,
): number {
const code = [];
for (let i = 0; i < code_size; i++)
code.push(Memory.read(parseInt(code_ptr), 'u8'));
return callback(code, code_size, offset /* TODO: user_data*/);
},
'iiiii');
Memory.write(callback_ptr, cb_ptr, '*');
}
return skipdata_struct;
}
/**
* Dereferences a pointer to a cs_insn strict to retrieve information about a disassembled instruction.
*
* @private
* @param insn_ptr - The pointer to the disassembled instruction.
* @returns Information about the disassembled instruction.
*/
private deref(insn_ptr: pointer_t<cs_insn>): cs_insn {
const insn_id: number = Memory.read(insn_ptr, 'u32');
const insn_addr: number = Memory.read(insn_ptr + 8, 'u64');
const insn_size: number = Memory.read(insn_ptr + 16, 'u16');
const insn_mn: string = Wrapper.UTF8ToString(insn_ptr + 42);
const insn_op_str: string = Wrapper.UTF8ToString(insn_ptr + 66 + 8);
const insn_bytes: number[] = [];
for (let j = 0; j < insn_size; j++) {
const byte = Memory.read(insn_ptr + 18 + j, 'u8');
insn_bytes.push(byte);
}
const insn: cs_insn = {
id: insn_id,
address: insn_addr,
size: insn_size,
mnemonic: insn_mn,
op_str: insn_op_str,
bytes: new Uint8Array(insn_bytes),
};
const detail_ptr: pointer_t<pointer_t<cs_detail>> = Memory.read(
insn_ptr + 238,
'*',
);
const has_detail = detail_ptr != Memory.nullptr;
if (has_detail) {
insn.detail = this.get_detail(detail_ptr);
}
if (this.opt_buffer) {
const heap = Wrapper.HEAPU8.buffer;
if (has_detail)
insn.detail.buffer = new Uint8Array(
heap,
Wrapper._cs_detail_buffer(insn_ptr),
DETAIL_SIZE,
);
insn.buffer = new Uint8Array(
heap,
Wrapper._cs_insn_buffer(insn_ptr),
DETAIL_SIZE,
);
}
return insn;
}
/**
* Converts an array of `cs_insn` objects into a pointer to an array of cs_insn structures.
*
* @private
* @param insns - Array of `cs_insn` objects to be converted.
* @returns A pointer to the array of cs_insn structures.
*/
private ref(insns: cs_insn[] | cs_insn): pointer_t<cs_insn[] | cs_insn> {
if (!Array.isArray(insns)) insns = [insns];
const count: number = insns.length;
const insns_ptr: pointer_t<cs_insn[]> = Memory.malloc(INSN_SIZE * count);
for (let i = 0; i < count; i++) {
const insn = insns[i];
const insn_ptr = insns_ptr + i * INSN_SIZE;
insn.id !== undefined &&
insn.id !== null &&
Memory.write(insn_ptr, insn.id, 'i32');
insn.address !== undefined &&
insn.address !== null &&
Memory.write(insn_ptr + 8, insn.address, 'i64');
insn.size !== undefined &&
insn.size !== null &&
Memory.write(insn_ptr + 16, insn.size, 'i16');
insn.mnemonic !== undefined &&
insn.mnemonic !== null &&
Memory.write(insn_ptr + 42, insn.mnemonic, 'char*');
insn.op_str !== undefined &&
insn.op_str !== null &&
Memory.write(insn_ptr + 66 + 8, insn.op_str, 'char*');
for (let j = 0; j < (insn.size || 0); j++) {
insn.bytes[j] !== undefined &&
insn.bytes[j] !== null &&
Memory.write(insn_ptr + 18 + j, insn.bytes[j], 'u8');
}
if (insn.detail) {
const detail: pointer_t<pointer_t<cs_detail>> = insn_ptr + 238;
const detail_ptr: pointer_t<cs_detail> = Memory.malloc(1864);
const arch_info_ptr: pointer_t<any> = detail_ptr + 96;
let arch;
let op_ptr;
let op;
Memory.write(detail, detail_ptr, '*');
for (let i = 0; i < (insn.detail.regs_read_count || 0); i++)
insn.detail.regs_read !== undefined &&
insn.detail.regs_read !== null &&
Memory.write(detail_ptr + i, insn.detail.regs_read[i], 'i16');
insn.detail.regs_read_count !== undefined &&
insn.detail.regs_read_count !== null &&
Memory.write(detail_ptr + 40, insn.detail.regs_read_count, 'ubyte');
for (let i = 0; i < (insn.detail.regs_write_count || 0); i++)
insn.detail.regs_write[i] !== undefined &&
insn.detail.regs_write[i] !== null &&
Memory.write(
detail_ptr + 42 + i,
insn.detail.regs_write[i],
'i16',
);
insn.detail.regs_write_count !== undefined &&
insn.detail.regs_write_count !== null &&
Memory.write(
detail_ptr + 82,
insn.detail.regs_write_count,
'ubyte',
);
for (let i = 0; i < (insn.detail.groups_count || 0); i++)
insn.detail.groups[i] !== undefined &&
insn.detail.groups[i] !== null &&
Memory.write(detail_ptr + 83 + i, insn.detail.groups[i], 'ubyte');
insn.detail.groups_count !== undefined &&
insn.detail.groups_count !== null &&
Memory.write(detail_ptr + 91, insn.detail.groups_count, 'ubyte');
insn.detail.writeback !== undefined &&
insn.detail.writeback !== null &&
Memory.write(detail_ptr + 92, insn.detail.writeback, 'bool');
switch (this.arch) {
case ARCH_ARM:
arch = insn.detail.arm;
arch.op_count !== undefined &&
arch.op_count !== null &&
Memory.write(arch_info_ptr + 32, arch.op_count, 'ubyte');
for (let i = 0; i < (arch.op_count || 0); i++) {
op_ptr = arch_info_ptr + 40 + i * 48;
op = arch.operands[i];
op.type !== undefined &&
op.type !== null &&
Memory.write(op_ptr + 12, op.type, 'i32');
switch (arch.operands[i].type || 0) {
case ARM.OP_SYSREG:
case ARM.OP_REG:
op.reg !== undefined &&
op.reg !== null &&
Memory.write(op_ptr + 16, op.reg, 'i32');
break;
case ARM.OP_IMM:
case ARM.OP_PIMM:
op.imm !== undefined &&
op.imm !== null &&
Memory.write(op_ptr + 16, op.imm, 'i32');
break;
case ARM.OP_FP:
op.fp !== undefined &&
op.fp !== null &&
Memory.write(op_ptr + 16, op.fp, 'double');
break;
case ARM.OP_SETEND:
op.setend !== undefined &&
op.setend !== null &&
Memory.write(op_ptr + 16, op.setend, 'i32');
break;
case ARM.OP_MEM:
op.mem.base !== undefined &&
op.mem.base !== null &&
Memory.write(op_ptr + 16, op.mem.base, 'i32');
op.mem.index !== undefined &&
op.mem.index !== null &&
Memory.write(op_ptr + 20, op.mem.index, 'i32');
op.mem.scale !== undefined &&
op.mem.scale !== null &&
Memory.write(op_ptr + 24, op.mem.scale, 'i32');
op.mem.disp !== undefined &&
op.mem.disp !== null &&
Memory.write(op_ptr + 28, op.mem.disp, 'i32');
op.mem.lshift !== undefined &&
op.mem.lshift !== null &&
Memory.write(op_ptr + 32, op.mem.lshift, 'i32');
break;
}
}
break;
case ARCH_ARM64:
arch = insn.detail.arm64;
arch.op_count !== undefined &&
arch.op_count !== null &&
Memory.write(arch_info_ptr + 7, arch.op_count, 'ubyte');
for (let i = 0; i < (arch.op_count || 0); i++) {
op_ptr = arch_info_ptr + 8 + i * 56;
op = arch.operands[i];
op.type !== undefined &&
op.type !== null &&
Memory.write(op_ptr + 20, op.type, 'i32');
switch (arch.operands[i].type || 0) {
case ARM64.OP_REG:
case ARM64.OP_REG_MRS:
case ARM64.OP_REG_MSR:
op.reg !== undefined &&
op.reg !== null &&
Memory.write(op_ptr + 32, op.reg, 'i32');
break;
case ARM64.OP_CIMM:
case ARM64.OP_IMM:
op.imm !== undefined &&
op.imm !== null &&
Memory.write(op_ptr + 32, op.imm, 'i64');
break;
case ARM64.OP_FP:
op.fp !== undefined &&
op.fp !== null &&
Memory.write(op_ptr + 32, op.fp, 'double');
break;
case ARM64.OP_PSTATE:
op.pstate !== undefined &&
op.pstate !== null &&
Memory.write(op_ptr + 32, op.pstate, 'i32');
break;
case ARM64.OP_SYS:
op.sys !== undefined &&
op.sys !== null &&
Memory.write(op_ptr + 32, op.sys, 'i32');
break;
case ARM64.OP_BARRIER:
op.barrier !== undefined &&
op.barrier !== null &&
Memory.write(op_ptr + 32, op.barrier, 'i32');
break;
case ARM64.OP_PREFETCH:
op.prefetch !== undefined &&
op.prefetch !== null &&
Memory.write(op_ptr + 32, op.prefetch, 'i32');
break;
case ARM64.OP_MEM:
op.mem.base !== undefined &&
op.mem.base !== null &&
Memory.write(op_ptr + 32, op.mem.base, 'i32');
op.mem.index !== undefined &&
op.mem.index !== null &&
Memory.write(op_ptr + 36, op.mem.index, 'i32');
op.mem.disp !== undefined &&
op.mem.disp !== null &&
Memory.write(op_ptr + 32, op.mem.disp, 'i32');
break;
case ARM64.OP_SVCR:
op.sme_index.reg !== undefined &&
op.sme_index.reg !== null &&
Memory.write(op_ptr + 32, op.sme_index.reg, 'i32');
op.sme_index.base !== undefined &&
op.sme_index.base !== null &&
Memory.write(op_ptr + 36, op.sme_index.base, 'i32');
op.sme_index.disp !== undefined &&
op.sme_index.disp !== null &&
Memory.write(op_ptr + 40, op.sme_index.disp, 'i32');
break;
}
}
break;
case ARCH_MIPS:
arch = insn.detail.mips;
arch.op_count !== undefined &&
arch.op_count !== null &&
Memory.write(arch_info_ptr + 0, arch.op_count, 'ubyte');
for (let i = 0; i < (arch.op_count || 0); i++) {
op_ptr = arch_info_ptr + 8 + i * 24;
op = arch.operands[i];
op.type !== undefined &&
op.type !== null &&
Memory.write(op_ptr, op.type, 'i32');
switch (arch.operands[i].type || 0) {
case MIPS.OP_REG:
op.reg !== undefined &&
op.reg !== null &&
Memory.write(op_ptr + 8, op.reg, 'i32');
break;
case MIPS.OP_IMM:
op.imm !== undefined &&
op.imm !== null &&
Memory.write(op_ptr + 8, op.imm, 'long');
break;
case MIPS.OP_MEM:
op.mem.base !== undefined &&
op.mem.base !== null &&
Memory.write(op_ptr + 8, op.mem.base, 'i32');
op.mem.disp !== undefined &&
op.mem.disp !== null &&
Memory.write(op_ptr + 12, op.mem.disp, 'long');
break;
}
}
break;
case ARCH_X86:
arch = insn.detail.x86;
arch.op_count !== undefined &&
arch.op_count !== null &&
Memory.write(arch_info_ptr + 64, arch.op_count, 'ubyte');
arch.disp !== undefined &&
arch.disp !== null &&
Memory.write(arch_info_ptr + 16, arch.disp, 'long');
for (let i = 0; i < (arch.op_count || 0); i++) {
op_ptr = arch_info_ptr + 72 + i * 48;
op = arch.operands[i];
op.type !== undefined &&
op.type !== null &&
Memory.write(op_ptr, op.type, 'i32');
switch (arch.operands[i].type || 0) {
case X86.OP_REG:
op.reg !== undefined &&
op.reg !== null &&
Memory.write(op_ptr + 8, op.reg, 'i32');
break;
case X86.OP_IMM:
op.imm !== undefined &&
op.imm !== null &&
Memory.write(op_ptr + 8, op.imm, 'long');
break;
case X86.OP_MEM:
op.mem.segment !== undefined &&
op.mem.segment !== null &&
Memory.write(op_ptr + 8, op.mem.segment, 'i32');
op.mem.base !== undefined &&
op.mem.base !== null &&
Memory.write(op_ptr + 12, op.mem.base, 'i32');
op.mem.index !== undefined &&
op.mem.index !== null &&
Memory.write(op_ptr + 16, op.mem.index, 'i32');
op.mem.scale !== undefined &&
op.mem.scale !== null &&
Memory.write(op_ptr + 20, op.mem.scale, 'i32');
break;
}
}
break;
case ARCH_PPC:
arch = insn.detail.ppc;
arch.op_count !== undefined &&
arch.op_count !== null &&
Memory.write(arch_info_ptr + 9, arch.op_count, 'ubyte');
for (let i = 0; i < (arch.op_count || 0); i++) {
op_ptr = arch_info_ptr + 16 + i * 24;
op = arch.operands[i];
op.type !== undefined &&
op.type !== null &&
Memory.write(op_ptr, op.type, 'i32');
switch (arch.operands[i].type || 0) {
case PPC.OP_REG:
op.reg !== undefined &&
op.reg !== null &&
Memory.write(op_ptr + 8, op.reg, 'i32');
break;
case PPC.OP_IMM:
op.imm !== undefined &&
op.imm !== null &&
Memory.write(op_ptr + 8, op.imm, 'long');
break;
case PPC.OP_CRX:
op.crx.scale !== undefined &&
op.crx.scale !== null &&
Memory.write(op_ptr + 8, op.crx.scale, 'u32');
op.crx.reg !== undefined &&
op.crx.reg !== null &&
Memory.write(op_ptr + 12, op.crx.reg, 'i32');
op.crx.cond !== undefined &&
op.crx.cond !== null &&
Memory.write(op_ptr + 16, op.crx.cond, 'i32');
break;
case PPC.OP_MEM:
op.mem.base !== undefined &&
op.mem.base !== null &&
Memory.write(op_ptr + 8, op.mem.base, 'i32');
op.mem.disp !== undefined &&
op.mem.disp !== null &&
Memory.write(op_ptr + 12, op.mem.disp, 'long');
break;
}
}
break;
case ARCH_SPARC:
arch = insn.detail.sparc;
arch.op_count !== undefined &&
arch.op_count !== null &&
Memory.write(arch_info_ptr + 8, arch.op_count, 'ubyte');
for (let i = 0; i < (arch.op_count || 0); i++) {
op_ptr = arch_info_ptr + 16 + i * 16;
op = arch.operands[i];
op.type !== undefined &&
op.type !== null &&
Memory.write(op_ptr, op.type, 'i32');
switch (arch.operands[i].type || 0) {
case SPARC.OP_REG:
op.reg !== undefined &&
op.reg !== null &&
Memory.write(op_ptr + 8, op.reg, 'i32');
break;
case SPARC.OP_IMM:
op.imm !== undefined &&
op.imm !== null &&
Memory.write(op_ptr, op.imm, 'i32');
break;
case SPARC.OP_MEM:
op.mem.base !== undefined &&
op.mem.base !== null &&
Memory.write(op_ptr + 8, op.mem.base, 'ubyte');
op.mem.index !== undefined &&
op.mem.index !== null &&
Memory.write(op_ptr + 9, op.mem.index, 'ubyte');
op.mem.disp !== undefined &&
op.mem.disp !== null &&
Memory.write(op_ptr + 12, op.mem.disp, 'i32');
break;
}
}
break;
case ARCH_SYSZ:
arch = insn.detail.sysz;
arch.op_count !== undefined &&
arch.op_count !== null &&
Memory.write(arch_info_ptr + 4, arch.op_count, 'ubyte');
for (let i = 0; i < (arch.op_count || 0); i++) {
op_ptr = arch_info_ptr + 8 + i * 32;
op = arch.operands[i];
op.type !== undefined &&
op.type !== null &&
Memory.write(op_ptr, op.type, 'i32');
switch (arch.operands[i].type || 0) {
case SYSZ.OP_REG:
op.reg !== undefined &&
op.reg !== null &&
Memory.write(op_ptr + 8, op.reg, 'i32');
break;
case SYSZ.OP_IMM: