mirror of
https://github.com/DoubleLabyrinth/navicat-keygen.git
synced 2019-12-02 05:10:56 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b29f20c46 | ||
|
|
0586ceefb6 | ||
|
|
bf2fb47a3a | ||
|
|
e81e0f0813 | ||
|
|
793d1e583c | ||
|
|
acd61f1822 | ||
|
|
d14695a524 | ||
|
|
7f84cf3294 | ||
|
|
f3b3ffdfa8 | ||
|
|
4d31408ea2 | ||
|
|
6e2ce547ec | ||
|
|
02f379e6f6 | ||
|
|
dfb8d38266 | ||
|
|
db95345644 | ||
|
|
10a119b483 | ||
|
|
5bd419e2ce | ||
|
|
e9cf2d1e3d | ||
|
|
29d886718c | ||
|
|
0994a86b2f | ||
|
|
23a7557a20 | ||
|
|
1a3a68f70e | ||
|
|
6722fbd562 | ||
|
|
0c0925b8a6 | ||
|
|
baf4f45e65 | ||
|
|
0ae8754462 | ||
|
|
fd2fe40394 | ||
|
|
33a4e9a179 | ||
|
|
1dd88e11ff | ||
|
|
802535f3ba | ||
|
|
0925e1ef06 | ||
|
|
e5103644a8 | ||
|
|
dca49e73e5 | ||
|
|
818a1d28e9 | ||
|
|
7ec1ea67c4 | ||
|
|
f7618bd3bc | ||
|
|
072734f041 | ||
|
|
eb828f5afa | ||
|
|
84b20b3b0e | ||
|
|
44d33cac08 | ||
|
|
415a782639 | ||
|
|
1408f08d96 | ||
|
|
9ff5da9a5c | ||
|
|
b65221bedb | ||
|
|
d371c9ebfd | ||
|
|
c3548220ab | ||
|
|
b588e7f608 | ||
|
|
5ffe7a198e | ||
|
|
e5300eee16 | ||
|
|
04fd1ba315 | ||
|
|
d4202a907c | ||
|
|
23987cb031 | ||
|
|
b9f6504c59 | ||
|
|
057d33fd9d | ||
|
|
b6aa89bb57 | ||
|
|
b3cfffddf6 | ||
|
|
cf945793e4 | ||
|
|
96f40aef26 | ||
|
|
28c2cfa290 | ||
|
|
ac271858f0 | ||
|
|
368d56b709 | ||
|
|
1f0298a4a8 |
@@ -0,0 +1,43 @@
|
||||
---
|
||||
name: Custom issue template
|
||||
about: Describe this issue template's purpose here.
|
||||
title: "[FAILURE][write OS type here] write your own description here"
|
||||
labels: failure report
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
BEFORE `navicat-patcher.exe` (Windows, Wine in Linux) or `navicat-patcher` (macOS) is run, you should make sure that your Navicat is official version, which means it has not been modified by anyone, and you should also make sure there's no `*.backup` files in Navicat installation folder.
|
||||
|
||||
If you still meet a failure, you can submit a failure report and please fill in the following:
|
||||
|
||||
1. What is your Navicat product? Check one of the following:
|
||||
- [ ] Navicat Premium
|
||||
- [ ] Navicat MySQL
|
||||
- [ ] Navicat Data Modeler
|
||||
- [ ] Navicat Report Viewer
|
||||
- [ ] Other, please write here: ______
|
||||
|
||||
2. What is your Navicat language version? Check one of the following:
|
||||
- [ ] English
|
||||
- [ ] Simplified Chinese
|
||||
- [ ] Traditional Chinese
|
||||
- [ ] Other, please write here: ______
|
||||
|
||||
3. What is your OS? Check one of the following:
|
||||
- [ ] Windows
|
||||
- [ ] macOS
|
||||
- [ ] Linux
|
||||
|
||||
4. Can you post console output here? If don't have, leave it empty.
|
||||
```
|
||||
Please post here
|
||||
```
|
||||
|
||||
5. If __Request Code__ or __Activation Code__ is shown, please post the content of `RegPrivateKey.pem` here:
|
||||
```
|
||||
Please post here
|
||||
```
|
||||
|
||||
6. If you have other information to provide, please write here.
|
||||
(If you don't have, leave it empty.)
|
||||
@@ -0,0 +1,46 @@
|
||||
---
|
||||
name: Failure report issue template
|
||||
about: A template for failure report.
|
||||
title: "[FAILURE][write OS type here] write your own description here"
|
||||
labels: failure report
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
BEFORE `navicat-patcher.exe` (Windows, Wine in Linux) or `navicat-patcher` (macOS) is run, you should make sure that your Navicat is official version, which means it has not been modified by anyone, and you should also make sure there's no `*.backup` files in Navicat installation folder.
|
||||
|
||||
If you still meet a failure, you can submit a failure report and please fill in the following:
|
||||
|
||||
1. What is your Navicat product? Check one of the following:
|
||||
- [ ] Navicat Premium
|
||||
- [ ] Navicat MySQL
|
||||
- [ ] Navicat Data Modeler
|
||||
- [ ] Navicat Report Viewer
|
||||
- [ ] Other, please write here: ______
|
||||
|
||||
2. What's your Navicat version number?
|
||||
Please write here: ______
|
||||
|
||||
3. What is your Navicat language version? Check one of the following:
|
||||
- [ ] English
|
||||
- [ ] Simplified Chinese
|
||||
- [ ] Traditional Chinese
|
||||
- [ ] Other, please write here: ______
|
||||
|
||||
4. What is your OS? Check one of the following:
|
||||
- [ ] Windows
|
||||
- [ ] macOS
|
||||
- [ ] Linux
|
||||
|
||||
5. Can you post console output here? If don't have, leave it empty.
|
||||
```
|
||||
Please post here
|
||||
```
|
||||
|
||||
6. If __Request Code__ or __Activation Code__ is shown, please post the content of `RegPrivateKey.pem` here:
|
||||
```
|
||||
Please post here
|
||||
```
|
||||
|
||||
7. If you have other information to provide, please write here.
|
||||
(If you don't have, leave it empty.)
|
||||
@@ -0,0 +1,46 @@
|
||||
---
|
||||
name: 失败报告模板
|
||||
about: 失败报告模板
|
||||
title: "[FAILURE][填写你的操作系统类型] 你的描述"
|
||||
labels: failure report
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
在运行 `navicat-patcher.exe` (Windows, Wine in Linux) 或者 `navicat-patcher` (macOS)之前,你应该确保你的Navicat是官方版本,即未被任何第三方修改,同时也应确保你的Navicat安装目录下没有 `*.backup` 文件。
|
||||
|
||||
如果激活依然失败了,你可以提交一份失败报告。请填写下面的内容:
|
||||
|
||||
1. 你的Navicat产品类型是什么? 选择下面一个:
|
||||
- [ ] Navicat Premium
|
||||
- [ ] Navicat MySQL
|
||||
- [ ] Navicat Data Modeler
|
||||
- [ ] Navicat Report Viewer
|
||||
- [ ] 其他,请写在这里:______
|
||||
|
||||
2. 你的Navicat版本号是多少?
|
||||
请写在这里:______
|
||||
|
||||
3. 你的Navicat产品语言版本是什么?选择下面一个:
|
||||
- [ ] English
|
||||
- [ ] Simplified Chinese
|
||||
- [ ] Traditional Chinese
|
||||
- [ ] 其他,请写在这里:______
|
||||
|
||||
4. 你的操作系统是什么?选择下面一个:
|
||||
- [ ] Windows
|
||||
- [ ] macOS
|
||||
- [ ] Linux
|
||||
|
||||
5. 你可以把命令行输出贴出来吗?如果你没有,请留空:
|
||||
```
|
||||
贴在这里
|
||||
```
|
||||
|
||||
6. 如果 __请求码__ 或者 __激活码__ 出现了,请把 `RegPrivateKey.pem` 的内容贴在这里:
|
||||
```
|
||||
贴在这里
|
||||
```
|
||||
|
||||
7. 如果你有其他信息要提供的,请写在这里:
|
||||
(如果你没有,请留空。)
|
||||
@@ -0,0 +1,286 @@
|
||||
# Navicat keygen - How does it work?
|
||||
|
||||
[中文版 How does it work?](HOW_DOES_IT_WORK.zh-CN.md)
|
||||
|
||||
## 1. Keyword Explanation.
|
||||
|
||||
* __Navicat Activation Public Key__
|
||||
|
||||
It is a __RSA-2048__ public key that Navicat used to encrypt or decrypt offline activation information.
|
||||
|
||||
It is stored in __navicat.exe__ as a kind of resource called __RCData__. The resource name is `"ACTIVATIONPUBKEY"`. You can see it by a kind of software [___Resource Hacker___](http://www.angusj.com/resourcehacker/). The public key is
|
||||
|
||||
```
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw1dqF3SkCaAAmMzs889I
|
||||
qdW9M2dIdh3jG9yPcmLnmJiGpBF4E9VHSMGe8oPAy2kJDmdNt4BcEygvssEfginv
|
||||
a5t5jm352UAoDosUJkTXGQhpAWMF4fBmBpO3EedG62rOsqMBgmSdAyxCSPBRJIOF
|
||||
R0QgZFbRnU0frj34fiVmgYiLuZSAmIbs8ZxiHPdp1oD4tUpvsFci4QJtYNjNnGU2
|
||||
WPH6rvChGl1IRKrxMtqLielsvajUjyrgOC6NmymYMvZNER3htFEtL1eQbCyTfDmt
|
||||
YyQ1Wt4Ot12lxf0wVIR5mcGN7XCXJRHOFHSf1gzXWabRSvmt1nrl7sW6cjxljuuQ
|
||||
awIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
```
|
||||
|
||||
If you have the corresponding private key, you can tell me. I would be very appreciated for your generous.
|
||||
|
||||
__NOTICE:__
|
||||
|
||||
Start from __Navicat Premium 12.0.25__, Navicat do not load this public key from resource in `navicat.exe`. Instead, the public key is stored in `libcc.dll` and has been encrypted. To avoid being replaced easily, the public key is split into 5 parts:
|
||||
|
||||
The following content is discovered from `libcc.dll` of __Navicat Premium x64 12.0.25 Simplified Chinese version__. The SHA256 value of `libcc.dll` is `607e0a84c75966b00f3d12fa833e91d159e4f51ac51b6ba66f98d0c3cbefdce0`.
|
||||
|
||||
I __DO NOT__ guarantee that offset values are absolutely correct in other versions. But __char strings__ and __immediate values__ are highly possible to be found.
|
||||
|
||||
1. At file offset `+0x01A12090` in `libcc.dll`, stored as __char string__:
|
||||
|
||||
```
|
||||
"D75125B70767B94145B47C1CB3C0755E
|
||||
7CCB8825C5DCE0C58ACF944E08280140
|
||||
9A02472FAFFD1CD77864BB821AE36766
|
||||
FEEDE6A24F12662954168BFA314BD950
|
||||
32B9D82445355ED7BC0B880887D650F5"
|
||||
```
|
||||
|
||||
2. At file offset `+0x0059D799` in `libcc.dll`, stored as __immediate value__ in a instruction:
|
||||
|
||||
```
|
||||
0xFE 0xEA 0xBC 0x01
|
||||
```
|
||||
|
||||
In decimal: `29158142`
|
||||
|
||||
3. At file offset `+0x01A11DA0` in `libcc.dll`, stored as __char string__:
|
||||
|
||||
```
|
||||
"E1CED09B9C2186BF71A70C0FE2F1E0AE
|
||||
F3BD6B75277AAB20DFAF3D110F75912B
|
||||
FB63AC50EC4C48689D1502715243A79F
|
||||
39FF2DE2BF15CE438FF885745ED54573
|
||||
850E8A9F40EE2FF505EB7476F95ADB78
|
||||
3B28CA374FAC4632892AB82FB3BF4715
|
||||
FCFE6E82D03731FC3762B6AAC3DF1C3B
|
||||
C646FE9CD3C62663A97EE72DB932A301
|
||||
312B4A7633100C8CC357262C39A2B3A6
|
||||
4B224F5276D5EDBDF0804DC3AC4B8351
|
||||
62BB1969EAEBADC43D2511D6E0239287
|
||||
81B167A48273B953378D3D2080CC0677
|
||||
7E8A2364F0234B81064C5C739A8DA28D
|
||||
C5889072BF37685CBC94C2D31D0179AD
|
||||
86D8E3AA8090D4F0B281BE37E0143746
|
||||
E6049CCC06899401264FA471C016A96C
|
||||
79815B55BBC26B43052609D9D175FBCD
|
||||
E455392F10E51EC162F51CF732E6BB39
|
||||
1F56BBFD8D957DF3D4C55B71CEFD54B1
|
||||
9C16D458757373E698D7E693A8FC3981
|
||||
5A8BF03BA05EA8C8778D38F9873D62B4
|
||||
460F41ACF997C30E7C3AF025FA171B5F
|
||||
5AD4D6B15E95C27F6B35AD61875E5505
|
||||
449B4E"
|
||||
```
|
||||
|
||||
4. At file offset `+0x0059D77F` in `libcc.dll`, stored as __immediate value__ in a instruction:
|
||||
|
||||
```
|
||||
0x59 0x08 0x01 0x00
|
||||
```
|
||||
|
||||
In decimal: `67673`
|
||||
|
||||
5. At file offset `+ 0x1A11D8C` in `libcc.dll`, stored as __char string__:
|
||||
|
||||
```
|
||||
"92933"
|
||||
```
|
||||
|
||||
Then output encrypted public key with format `"%s%d%s%d%s"`. The order is the same as it lists:
|
||||
|
||||
```
|
||||
|
||||
D75125B70767B94145B47C1CB3C0755E7CCB8825C5DCE0C58ACF944E082801409A02472FAFFD1CD77864BB821AE36766FEEDE6A24F12662954168BFA314BD95032B9D82445355ED7BC0B880887D650F529158142E1CED09B9C2186BF71A70C0FE2F1E0AEF3BD6B75277AAB20DFAF3D110F75912BFB63AC50EC4C48689D1502715243A79F39FF2DE2BF15CE438FF885745ED54573850E8A9F40EE2FF505EB7476F95ADB783B28CA374FAC4632892AB82FB3BF4715FCFE6E82D03731FC3762B6AAC3DF1C3BC646FE9CD3C62663A97EE72DB932A301312B4A7633100C8CC357262C39A2B3A64B224F5276D5EDBDF0804DC3AC4B835162BB1969EAEBADC43D2511D6E023928781B167A48273B953378D3D2080CC06777E8A2364F0234B81064C5C739A8DA28DC5889072BF37685CBC94C2D31D0179AD86D8E3AA8090D4F0B281BE37E0143746E6049CCC06899401264FA471C016A96C79815B55BBC26B43052609D9D175FBCDE455392F10E51EC162F51CF732E6BB391F56BBFD8D957DF3D4C55B71CEFD54B19C16D458757373E698D7E693A8FC39815A8BF03BA05EA8C8778D38F9873D62B4460F41ACF997C30E7C3AF025FA171B5F5AD4D6B15E95C27F6B35AD61875E5505449B4E6767392933
|
||||
|
||||
```
|
||||
|
||||
This encrypted public key can be decrypted by my another repo: [how-does-navicat-encrypt-password](https://github.com/DoubleLabyrinth/how-does-navicat-encrypt-password), while the key used is `b'23970790'`.
|
||||
|
||||
Example:
|
||||
|
||||
```cmd
|
||||
E:\GitHub>git clone https://github.com/DoubleLabyrinth/how-does-navicat-encrypt-password.git
|
||||
...
|
||||
E:\GitHub>cd how-does-navicat-encrypt-password\python3
|
||||
E:\GitHub\how-does-navicat-encrypt-password\python3>python
|
||||
Python 3.6.3 (v3.6.3:2c5fed8, Oct 3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)] on win32
|
||||
Type "help", "copyright", "credits" or "license" for more information.
|
||||
>>> from NavicatCrypto import *
|
||||
>>> cipher = Navicat11Crypto(b'23970790')
|
||||
>>> print(cipher.DecryptString('D75125B70767B94145B47C1CB3C0755E7CCB8825C5DCE0C58ACF944E082801409A02472FAFFD1CD77864BB821AE36766FEEDE6A24F12662954168BFA314BD95032B9D82445355ED7BC0B880887D650F529158142E1CED09B9C2186BF71A70C0FE2F1E0AEF3BD6B75277AAB20DFAF3D110F75912BFB63AC50EC4C48689D1502715243A79F39FF2DE2BF15CE438FF885745ED54573850E8A9F40EE2FF505EB7476F95ADB783B28CA374FAC4632892AB82FB3BF4715FCFE6E82D03731FC3762B6AAC3DF1C3BC646FE9CD3C62663A97EE72DB932A301312B4A7633100C8CC357262C39A2B3A64B224F5276D5EDBDF0804DC3AC4B835162BB1969EAEBADC43D2511D6E023928781B167A48273B953378D3D2080CC06777E8A2364F0234B81064C5C739A8DA28DC5889072BF37685CBC94C2D31D0179AD86D8E3AA8090D4F0B281BE37E0143746E6049CCC06899401264FA471C016A96C79815B55BBC26B43052609D9D175FBCDE455392F10E51EC162F51CF732E6BB391F56BBFD8D957DF3D4C55B71CEFD54B19C16D458757373E698D7E693A8FC39815A8BF03BA05EA8C8778D38F9873D62B4460F41ACF997C30E7C3AF025FA171B5F5AD4D6B15E95C27F6B35AD61875E5505449B4E6767392933'))
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw1dqF3SkCaAAmMzs889I
|
||||
qdW9M2dIdh3jG9yPcmLnmJiGpBF4E9VHSMGe8oPAy2kJDmdNt4BcEygvssEfginv
|
||||
a5t5jm352UAoDosUJkTXGQhpAWMF4fBmBpO3EedG62rOsqMBgmSdAyxCSPBRJIOF
|
||||
R0QgZFbRnU0frj34fiVmgYiLuZSAmIbs8ZxiHPdp1oD4tUpvsFci4QJtYNjNnGU2
|
||||
WPH6rvChGl1IRKrxMtqLielsvajUjyrgOC6NmymYMvZNER3htFEtL1eQbCyTfDmt
|
||||
YyQ1Wt4Ot12lxf0wVIR5mcGN7XCXJRHOFHSf1gzXWabRSvmt1nrl7sW6cjxljuuQ
|
||||
awIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
```
|
||||
|
||||
__NOTICE:__
|
||||
|
||||
Start from __Navicat Premium 12.1.11__, Navicat do not load the public key through the method I talked before. Of course, the public key is still stored in `libcc.dll`. When Navicat starts, it encrypts the public key by an 8-bytes-long XOR key and stores the ciphertext in static area. When verifing __Activation Code__, Navicat will regenerate the 8-bytes-long XOR key and decrypts the ciphertext in static area to get the public key.
|
||||
|
||||
In `libcc.dll`, x64 version, you can find some instructions that looks like:
|
||||
|
||||
```asm
|
||||
xor eax, 'M'
|
||||
mov byte_xxxxxx, al
|
||||
...
|
||||
xor eax, 'I'
|
||||
mov byte_xxxxxx, al
|
||||
...
|
||||
xor eax, 'I'
|
||||
mov byte_xxxxxx, al
|
||||
...
|
||||
xor eax, 'B'
|
||||
mov byte_xxxxxx, al
|
||||
...
|
||||
xor eax, 'I'
|
||||
mov byte_xxxxxx, al
|
||||
...
|
||||
xor eax, 'j'
|
||||
mov byte_xxxxxx, al
|
||||
...
|
||||
...
|
||||
```
|
||||
|
||||
* __Request Code__
|
||||
|
||||
It is a Base64 string that represents 256-bytes-long data, while the 256-bytes-long data is the cipher text of __Offline Activation Request Information__ encrypted by __Navicat Activation Public Key__.
|
||||
|
||||
* __Offline Activation Request Information__
|
||||
|
||||
It is just a JSON-style ASCII string which contains 3 items. They are `"K"`, `"DI"` and `"P"` respectively, which represent __snKey__, __DeviceIdentifier__ (related with your machine), __Platform__ (OS Type).
|
||||
|
||||
Like
|
||||
|
||||
```
|
||||
{"K": "xxxxxxxxxxxxxxxx", "DI": "yyyyyyyyyyyyy", "P": "WIN8"}
|
||||
```
|
||||
|
||||
* __Activation Code__
|
||||
|
||||
It is a Base64 string that represents 256-bytes-long data, while the 256-bytes-long data is the cipher text of the __Offline Activation Response Information__ encrypted by __Navicat Activation Private Key__. So far, we don't know the official activation private key and we have to replace it in `navicat.exe` and `libcc.dll`.
|
||||
|
||||
* __Offline Activation Response Information__
|
||||
|
||||
Just like __Offline Activation Request Information__, it is also a JSON-style ASCII string. But it contains 5 items. They are `"K"`, `"N"`, `"O"`, `"T"` and `"DI"` respectively.
|
||||
|
||||
`"K"` and `"DI"` has the same meaning that is mentioned in __Offline Activation Request Information__ and must be the same with the corresponding items in __Offline Activation Request Information__.
|
||||
|
||||
`"N"`, `"O"`, `"T"` represent __Name__, __Organization__, __Timestamp__ respectively. __Name__ and __Organization__ are UTF-8 strings and the type of __Timestamp__ can be string or integer. (Thanks for discoveries from @Wizr, issue #10)
|
||||
|
||||
`"T"` can be omitted.
|
||||
|
||||
* __snKey__
|
||||
|
||||
It is a 4-block-long string, while every block is 4-chars-long.
|
||||
|
||||
__snKey__ is generated by 10-bytes-long data. In order to explain it easily, I use __uint8_t data[10]__ to represent the 10-bytes-long data.
|
||||
|
||||
1. __data[0]__ and __data[1]__ must be `0x68` and `0x2A` respectively.
|
||||
|
||||
These two bytes are Naivcat signature number.
|
||||
|
||||
2. __data[2]__, __data[3]__ and __data[4]__ can be any byte. Just set them whatever you want.
|
||||
|
||||
3. __data[5]__ and __data[6]__ are product language signatures.
|
||||
|
||||
| Language | data[5] | data[6] | Discoverer |
|
||||
|------------|:---------:|:---------:|-----------------|
|
||||
| English | 0xAC | 0x88 | |
|
||||
| 简体中文 | 0xCE | 0x32 | |
|
||||
| 繁體中文 | 0xAA | 0x99 | |
|
||||
| 日本語 | 0xAD | 0x82 | @dragonflylee |
|
||||
| Polski | 0xBB | 0x55 | @dragonflylee |
|
||||
| Español | 0xAE | 0x10 | @dragonflylee |
|
||||
| Français | 0xFA | 0x20 | @Deltafox79 |
|
||||
| Deutsch | 0xB1 | 0x60 | @dragonflylee |
|
||||
| 한국어 | 0xB5 | 0x60 | @dragonflylee |
|
||||
| Русский | 0xEE | 0x16 | @dragonflylee |
|
||||
| Português | 0xCD | 0x49 | @dragonflylee |
|
||||
|
||||
4. __data[7]__ is Navicat product ID. (Thanks @dragonflylee and @Deltafox79)
|
||||
|
||||
|Product Name |Enterprise|Standard|Educational|Essentials|
|
||||
|---------------------|:--------:|:------:|:---------:|:--------:|
|
||||
|Navicat Report Viewer|0x0B | | | |
|
||||
|Navicat Data Modeler | |0x47 |0x4A | |
|
||||
|Navicat Premium |0x65 | |0x66 |0x67 |
|
||||
|Navicat MySQL |0x68 |0x69 |0x6A |0x6B |
|
||||
|Navicat PostgreSQL |0x6C |0x6D |0x6E |0x6F |
|
||||
|Navicat Oracle |0x70 |0x71 |0x72 |0x73 |
|
||||
|Navicat SQL Server |0x74 |0x75 |0x76 |0x77 |
|
||||
|Navicat SQLite |0x78 |0x79 |0x7A |0x7B |
|
||||
|Navicat MariaDB |0x7C |0x7D |0x7E |0x7F |
|
||||
|Navicat MongoDB |0x80 |0x81 |0x82 | |
|
||||
|
||||
5. High 4 bits of __data[8]__ represents __major version number__.
|
||||
|
||||
Low 4 bits is unknown, but we can use it to delay activation deadline. Possible values are `0000` or `0001`.
|
||||
|
||||
__Example:__
|
||||
|
||||
For __Navicat 12 x64__: High 4 bits must be `1100`, which is the binary of number `12`.
|
||||
For __Navicat 11 x64__: High 4 bits must be `1011`, which is the binary of number `11`.
|
||||
|
||||
6. __data[9]__ is unknown, but you can set it by `0xFD`, `0xFC` or `0xFB` if you want to use __not-for-resale license__.
|
||||
|
||||
According to symbol information in __Navicat 12 for Mac x64__ version:
|
||||
|
||||
* `0xFB` is __Not-For-Resale-30-days__ license.
|
||||
* `0xFC` is __Not-For-Resale-90-days__ license.
|
||||
* `0xFD` is __Not-For-Resale-365-days__ license.
|
||||
* `0xFE` is __Not-For-Resale__ license.
|
||||
* `0xFF` is __Site__ license.
|
||||
|
||||
After `uint8_t data[10]` is ready, Navicat uses __DES__ with __ECB mode__ to encrypt the last 8 bytes of `uint8_t data[10]` which are from __data[2]__ to __data[9]__.
|
||||
|
||||
The DES key is:
|
||||
|
||||
```cpp
|
||||
unsigned char DESKey = { 0x64, 0xAD, 0xF3, 0x2F, 0xAE, 0xF2, 0x1A, 0x27 };
|
||||
```
|
||||
|
||||
Then use Base32 to encode `uint8_t data[10]` whose encode table is
|
||||
|
||||
```cpp
|
||||
char EncodeTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
||||
```
|
||||
|
||||
After encoding, you will get a 16-char-long string starting with `"NAV"`.
|
||||
|
||||
Finally, divide the 16-char-long string to four 4-chars-long blocks and join them with `"-"` then you will get __snKey__.
|
||||
|
||||
## 2. Activation Process
|
||||
|
||||
1. Check whether __snKey__ that user inputs is valid.
|
||||
|
||||
2. After user clicks `Activate`, Navicat will start online activation first. If fails, user can choose offline activation.
|
||||
|
||||
3. Navicat will use the __snKey__ that user inputs and some information collected from user's machine to generate __Offline Activation Request Information__. Then Navicat will encrypt it by __Navicat Activation Public Key__ and return a Base64-encoded string as __Request Code__.
|
||||
|
||||
4. In legal way, the __Request Code__ should be sent to Navicat official activation server by a Internet-accessible computer. And Navicat official activation server will return a legal __Activation Code__.
|
||||
|
||||
But now, we use keygen to play the official activation server's role.
|
||||
|
||||
1. According to the __Request Code__, get `"DI"` value and `"K"` value.
|
||||
|
||||
2. Fill __Offline Activation Response Information__ with `"K"` value, name, organization name, `"DI"` value and, if need, `"T"` value.
|
||||
|
||||
3. Encrypt __Offline Activation Response Information__ by __Navicat Activation Private Key__ and you will get 256-byte-long data.
|
||||
|
||||
4. Encode the 256-byte-long data by Base64. The result is __Activation Code__.
|
||||
|
||||
5. After user input __Activation Code__, offline activation is done successfully.
|
||||
|
||||
@@ -0,0 +1,282 @@
|
||||
# Navicat keygen - 注册机是怎么工作的?
|
||||
|
||||
## 1. 关键词解释.
|
||||
|
||||
* __Navicat激活公钥__
|
||||
|
||||
这是一个2048位的RSA公钥,Navicat使用这个公钥来完成相关激活信息的加密和解密。
|
||||
|
||||
这个公钥被作为 __RCData__ 类型的资源储存在 __navicat.exe__ 当中。资源名为`"ACTIVATIONPUBKEY"`。你可以使用一个叫[Resource Hacker](http://www.angusj.com/resourcehacker/)的软件来查看它。这个公钥的具体内容为:
|
||||
|
||||
```
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw1dqF3SkCaAAmMzs889I
|
||||
qdW9M2dIdh3jG9yPcmLnmJiGpBF4E9VHSMGe8oPAy2kJDmdNt4BcEygvssEfginv
|
||||
a5t5jm352UAoDosUJkTXGQhpAWMF4fBmBpO3EedG62rOsqMBgmSdAyxCSPBRJIOF
|
||||
R0QgZFbRnU0frj34fiVmgYiLuZSAmIbs8ZxiHPdp1oD4tUpvsFci4QJtYNjNnGU2
|
||||
WPH6rvChGl1IRKrxMtqLielsvajUjyrgOC6NmymYMvZNER3htFEtL1eQbCyTfDmt
|
||||
YyQ1Wt4Ot12lxf0wVIR5mcGN7XCXJRHOFHSf1gzXWabRSvmt1nrl7sW6cjxljuuQ
|
||||
awIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
```
|
||||
|
||||
如果您有相应的私钥并乐意公开的话欢迎联系我,我将非常感谢您的慷慨。
|
||||
|
||||
__注意:__
|
||||
|
||||
从 __Navicat Premium 12.0.25__ 开始,Navicat不再从`navicat.exe`的资源中加载私钥。事实上,公钥转为从`libcc.dll`中加载,并且已经被加密。与此同时,为了防止被轻松地替换,加密的公钥被分到5个地方储存:
|
||||
|
||||
以下内容是从 __Navicat Premium x64 12.0.25 简体中文版__ 的`libcc.dll`中发现的,`libcc.dll`的SHA256值为`607e0a84c75966b00f3d12fa833e91d159e4f51ac51b6ba66f98d0c3cbefdce0`。我不保证在Navicat的其他版本中相关偏移量和下述的相同,但相关的 __字符串__ 以及 __立即数__ 是很可能找得到的。
|
||||
|
||||
1. 在`libcc.dll`中,文件偏移量`+0x01A12090`的地方,储存了加密公钥的第一部分,以 __字符串__ 的形式储存:
|
||||
|
||||
```
|
||||
"D75125B70767B94145B47C1CB3C0755E
|
||||
7CCB8825C5DCE0C58ACF944E08280140
|
||||
9A02472FAFFD1CD77864BB821AE36766
|
||||
FEEDE6A24F12662954168BFA314BD950
|
||||
32B9D82445355ED7BC0B880887D650F5"
|
||||
```
|
||||
|
||||
2. 在`libcc.dll`中,文件偏移量`+0x0059D799`的地方,储存了加密公钥的第二部分,以 __立即数__ 的形式储存在一条指令中:
|
||||
|
||||
```
|
||||
0xFE 0xEA 0xBC 0x01
|
||||
```
|
||||
|
||||
相应的十进制值为: `29158142`
|
||||
|
||||
3. 在`libcc.dll`中,文件偏移量`+0x01A11DA0`的地方,储存了加密公钥的第三部分,以 __字符串__ 的形式储存:
|
||||
|
||||
```
|
||||
"E1CED09B9C2186BF71A70C0FE2F1E0AE
|
||||
F3BD6B75277AAB20DFAF3D110F75912B
|
||||
FB63AC50EC4C48689D1502715243A79F
|
||||
39FF2DE2BF15CE438FF885745ED54573
|
||||
850E8A9F40EE2FF505EB7476F95ADB78
|
||||
3B28CA374FAC4632892AB82FB3BF4715
|
||||
FCFE6E82D03731FC3762B6AAC3DF1C3B
|
||||
C646FE9CD3C62663A97EE72DB932A301
|
||||
312B4A7633100C8CC357262C39A2B3A6
|
||||
4B224F5276D5EDBDF0804DC3AC4B8351
|
||||
62BB1969EAEBADC43D2511D6E0239287
|
||||
81B167A48273B953378D3D2080CC0677
|
||||
7E8A2364F0234B81064C5C739A8DA28D
|
||||
C5889072BF37685CBC94C2D31D0179AD
|
||||
86D8E3AA8090D4F0B281BE37E0143746
|
||||
E6049CCC06899401264FA471C016A96C
|
||||
79815B55BBC26B43052609D9D175FBCD
|
||||
E455392F10E51EC162F51CF732E6BB39
|
||||
1F56BBFD8D957DF3D4C55B71CEFD54B1
|
||||
9C16D458757373E698D7E693A8FC3981
|
||||
5A8BF03BA05EA8C8778D38F9873D62B4
|
||||
460F41ACF997C30E7C3AF025FA171B5F
|
||||
5AD4D6B15E95C27F6B35AD61875E5505
|
||||
449B4E"
|
||||
```
|
||||
|
||||
4. 在`libcc.dll`中,文件偏移量`+0x0059D77F`的地方,储存了加密公钥的第四部分,以 __立即数__ 的形式储存在一条指令中:
|
||||
|
||||
```
|
||||
0x59 0x08 0x01 0x00
|
||||
```
|
||||
|
||||
相应的十进制值为: `67673`
|
||||
|
||||
5. 在`libcc.dll`中,文件偏移量`+0x01A11D8C`的地方,储存了加密公钥的第五部分,以 __字符串__ 的形式储存:
|
||||
|
||||
```
|
||||
"92933"
|
||||
```
|
||||
|
||||
这五部分按照`"%s%d%s%d%s"`的形式输出则为加密的公钥,顺序和上述的顺序相同,具体的输出为:
|
||||
|
||||
```
|
||||
|
||||
D75125B70767B94145B47C1CB3C0755E7CCB8825C5DCE0C58ACF944E082801409A02472FAFFD1CD77864BB821AE36766FEEDE6A24F12662954168BFA314BD95032B9D82445355ED7BC0B880887D650F529158142E1CED09B9C2186BF71A70C0FE2F1E0AEF3BD6B75277AAB20DFAF3D110F75912BFB63AC50EC4C48689D1502715243A79F39FF2DE2BF15CE438FF885745ED54573850E8A9F40EE2FF505EB7476F95ADB783B28CA374FAC4632892AB82FB3BF4715FCFE6E82D03731FC3762B6AAC3DF1C3BC646FE9CD3C62663A97EE72DB932A301312B4A7633100C8CC357262C39A2B3A64B224F5276D5EDBDF0804DC3AC4B835162BB1969EAEBADC43D2511D6E023928781B167A48273B953378D3D2080CC06777E8A2364F0234B81064C5C739A8DA28DC5889072BF37685CBC94C2D31D0179AD86D8E3AA8090D4F0B281BE37E0143746E6049CCC06899401264FA471C016A96C79815B55BBC26B43052609D9D175FBCDE455392F10E51EC162F51CF732E6BB391F56BBFD8D957DF3D4C55B71CEFD54B19C16D458757373E698D7E693A8FC39815A8BF03BA05EA8C8778D38F9873D62B4460F41ACF997C30E7C3AF025FA171B5F5AD4D6B15E95C27F6B35AD61875E5505449B4E6767392933
|
||||
|
||||
```
|
||||
|
||||
这个加密的公钥可以用我的另外一个repo([how-does-navicat-encrypt-password](https://github.com/DoubleLabyrinth/how-does-navicat-encrypt-password))解密,其中密钥为`b'23970790'`。
|
||||
|
||||
例如:
|
||||
|
||||
```cmd
|
||||
E:\GitHub>git clone https://github.com/DoubleLabyrinth/how-does-navicat-encrypt-password.git
|
||||
...
|
||||
E:\GitHub>cd how-does-navicat-encrypt-password\python3
|
||||
E:\GitHub\how-does-navicat-encrypt-password\python3>python
|
||||
Python 3.6.3 (v3.6.3:2c5fed8, Oct 3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)] on win32
|
||||
Type "help", "copyright", "credits" or "license" for more information.
|
||||
>>> from NavicatCrypto import *
|
||||
>>> cipher = Navicat11Crypto(b'23970790')
|
||||
>>> print(cipher.DecryptString('D75125B70767B94145B47C1CB3C0755E7CCB8825C5DCE0C58ACF944E082801409A02472FAFFD1CD77864BB821AE36766FEEDE6A24F12662954168BFA314BD95032B9D82445355ED7BC0B880887D650F529158142E1CED09B9C2186BF71A70C0FE2F1E0AEF3BD6B75277AAB20DFAF3D110F75912BFB63AC50EC4C48689D1502715243A79F39FF2DE2BF15CE438FF885745ED54573850E8A9F40EE2FF505EB7476F95ADB783B28CA374FAC4632892AB82FB3BF4715FCFE6E82D03731FC3762B6AAC3DF1C3BC646FE9CD3C62663A97EE72DB932A301312B4A7633100C8CC357262C39A2B3A64B224F5276D5EDBDF0804DC3AC4B835162BB1969EAEBADC43D2511D6E023928781B167A48273B953378D3D2080CC06777E8A2364F0234B81064C5C739A8DA28DC5889072BF37685CBC94C2D31D0179AD86D8E3AA8090D4F0B281BE37E0143746E6049CCC06899401264FA471C016A96C79815B55BBC26B43052609D9D175FBCDE455392F10E51EC162F51CF732E6BB391F56BBFD8D957DF3D4C55B71CEFD54B19C16D458757373E698D7E693A8FC39815A8BF03BA05EA8C8778D38F9873D62B4460F41ACF997C30E7C3AF025FA171B5F5AD4D6B15E95C27F6B35AD61875E5505449B4E6767392933'))
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw1dqF3SkCaAAmMzs889I
|
||||
qdW9M2dIdh3jG9yPcmLnmJiGpBF4E9VHSMGe8oPAy2kJDmdNt4BcEygvssEfginv
|
||||
a5t5jm352UAoDosUJkTXGQhpAWMF4fBmBpO3EedG62rOsqMBgmSdAyxCSPBRJIOF
|
||||
R0QgZFbRnU0frj34fiVmgYiLuZSAmIbs8ZxiHPdp1oD4tUpvsFci4QJtYNjNnGU2
|
||||
WPH6rvChGl1IRKrxMtqLielsvajUjyrgOC6NmymYMvZNER3htFEtL1eQbCyTfDmt
|
||||
YyQ1Wt4Ot12lxf0wVIR5mcGN7XCXJRHOFHSf1gzXWabRSvmt1nrl7sW6cjxljuuQ
|
||||
awIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
```
|
||||
|
||||
__注意:__
|
||||
|
||||
从 __Navicat Premium 12.1.11__ 开始,Navicat不在用上面说的方法加载密钥。当然密钥还是储存在`libcc.dll`文件中。当Navicat启动时,它会用8字节长的XOR密钥来加密公钥,并储存到一个静态数据区中。当验证 __激活码__ 时,Navicat会重新生成一样的8字节XOR密钥,并解密在静态储存区中的密文,从而获取公钥。
|
||||
|
||||
在`libcc.dll`,x64版本中,你会看到如下的几条指令:
|
||||
|
||||
```asm
|
||||
xor eax, 'M'
|
||||
mov byte_xxxxxx, al
|
||||
...
|
||||
xor eax, 'I'
|
||||
mov byte_xxxxxx, al
|
||||
...
|
||||
xor eax, 'I'
|
||||
mov byte_xxxxxx, al
|
||||
...
|
||||
xor eax, 'B'
|
||||
mov byte_xxxxxx, al
|
||||
...
|
||||
xor eax, 'I'
|
||||
mov byte_xxxxxx, al
|
||||
...
|
||||
xor eax, 'j'
|
||||
mov byte_xxxxxx, al
|
||||
...
|
||||
...
|
||||
```
|
||||
|
||||
* __请求码__
|
||||
|
||||
这是一个Base64编码的字符串,代表的是长度为256字节的数据。这256字节的数据是 __离线激活信息__ 用 __Navicat激活公钥__ 加密的密文。
|
||||
|
||||
* __离线激活请求信息__
|
||||
|
||||
这是一个JSON风格的字符串。它包含了3个Key:`"K"`、`"DI"`和`"P"`,分别代表 __序列号__、__设备识别码__(与你的电脑硬件信息相关)和 __平台__ (其实就是操作系统类型)。
|
||||
|
||||
例如:
|
||||
|
||||
```
|
||||
{"K": "xxxxxxxxxxxxxxxx", "DI": "yyyyyyyyyyyyy", "P": "WIN8"}
|
||||
```
|
||||
|
||||
* __激活码__
|
||||
|
||||
这是一个Base64编码的字符串,代表的是长度为256字节的数据。这256字节的数据是 __离线激活回复信息__ 用 __Navicat激活私钥__ 加密的密文。目前我们不知道官方的 __Navicat激活私钥__,所以我们得替换掉软件里的公钥。
|
||||
|
||||
* __离线激活回复信息__
|
||||
|
||||
和 __离线激活请求信息__ 一样,它也是一个JSON风格的字符串。但是它包含5个Key,分别为`"K"`、`"N"`、`"O"`、`"T"` 和 `"DI"`.
|
||||
|
||||
`"K"` 和 `"DI"` 的意义与 __离线激活请求信息__ 中的相同,且Value必须与 __离线激活请求信息__ 中的相同。
|
||||
|
||||
`"N"`、`"O"`、`"T"` 分别代表 __注册名__、__组织__、__授权时间__。
|
||||
|
||||
__注册名__ 和 __组织__ 的值类型为UTF-8编码的字符串。__授权时间__ 的值类型可以为字符串或整数(感谢@Wizr在issue #10中的报告)。
|
||||
|
||||
`"T"` 可以被省略。
|
||||
|
||||
* __序列号__
|
||||
|
||||
这是一个被分为了4个部分的字符串,其中每个部分都是4个字符长。
|
||||
|
||||
__序列号__ 是通过10个字节的数据来生成的。为了表达方便,我用 __uint8_t data[10]__ 来表示这10个字节。
|
||||
|
||||
1. __data[0]__ 和 __data[1]__ 必须分别为 `0x68` 和 `0x2A`。
|
||||
|
||||
这两个字节为Navicat的标志数。
|
||||
|
||||
2. __data[2]__、__data[3]__ 和 __data[4]__ 可以是任意字节,你想设成什么都行。
|
||||
|
||||
3. __data[5]__ 和 __data[6]__ 是Navicat的语言标志,值如下:
|
||||
|
||||
| 语言类型 | data[5] | data[6] | 发现者 |
|
||||
|------------|:---------:|:---------:|-----------------|
|
||||
| English | 0xAC | 0x88 | |
|
||||
| 简体中文 | 0xCE | 0x32 | |
|
||||
| 繁體中文 | 0xAA | 0x99 | |
|
||||
| 日本語 | 0xAD | 0x82 | @dragonflylee |
|
||||
| Polski | 0xBB | 0x55 | @dragonflylee |
|
||||
| Español | 0xAE | 0x10 | @dragonflylee |
|
||||
| Français | 0xFA | 0x20 | @Deltafox79 |
|
||||
| Deutsch | 0xB1 | 0x60 | @dragonflylee |
|
||||
| 한국어 | 0xB5 | 0x60 | @dragonflylee |
|
||||
| Русский | 0xEE | 0x16 | @dragonflylee |
|
||||
| Português | 0xCD | 0x49 | @dragonflylee |
|
||||
|
||||
4. __data[7]__ 是Navicat产品ID。(感谢 @dragonflylee 和 @Deltafox79提供的数据)
|
||||
|
||||
|产品名 |Enterprise|Standard|Educational|Essentials|
|
||||
|---------------------|:--------:|:------:|:---------:|:--------:|
|
||||
|Navicat Report Viewer|0x0B | | | |
|
||||
|Navicat Data Modeler | |0x47 |0x4A | |
|
||||
|Navicat Premium |0x65 | |0x66 |0x67 |
|
||||
|Navicat MySQL |0x68 |0x69 |0x6A |0x6B |
|
||||
|Navicat PostgreSQL |0x6C |0x6D |0x6E |0x6F |
|
||||
|Navicat Oracle |0x70 |0x71 |0x72 |0x73 |
|
||||
|Navicat SQL Server |0x74 |0x75 |0x76 |0x77 |
|
||||
|Navicat SQLite |0x78 |0x79 |0x7A |0x7B |
|
||||
|Navicat MariaDB |0x7C |0x7D |0x7E |0x7F |
|
||||
|Navicat MongoDB |0x80 |0x81 |0x82 | |
|
||||
|
||||
5. __data[8]__ 的高4位代表 __版本号__。低4位未知,但可以用来延长激活期限,可取的值有`0000`和`0001`。
|
||||
|
||||
例如:
|
||||
|
||||
对于 __Navicat 12__: 高4位必须是`1100`,为`12`的二进制形式。
|
||||
对于 __Navicat 11__: 高4位必须是`1011`,为`11`的二进制形式。
|
||||
|
||||
6. __data[9]__ 目前暂未知,但如果你想要 __not-for-resale license__ 的话可以设成`0xFD`、`0xFC`或`0xFB`。
|
||||
|
||||
根据 __Navicat 12 for Mac x64__ 版本残留的符号信息可知:
|
||||
|
||||
* `0xFB`是 __Not-For-Resale-30-days__ license.
|
||||
* `0xFC`是 __Not-For-Resale-90-days__ license.
|
||||
* `0xFD`是 __Not-For-Resale-365-days__ license.
|
||||
* `0xFE`是 __Not-For-Resale__ license.
|
||||
* `0xFF`是 __Site__ license.
|
||||
|
||||
之后Navicat使用 __ECB__ 模式的 __DES__ 算法来加密 __data[10]__ 的后8字节,也就是 __data[2]__ 到 __data[9]__ 的部分。
|
||||
|
||||
相应的DES密钥为:
|
||||
|
||||
```cpp
|
||||
unsigned char DESKey = { 0x64, 0xAD, 0xF3, 0x2F, 0xAE, 0xF2, 0x1A, 0x27 };
|
||||
```
|
||||
|
||||
之后使用Base32编码 __data[10]__,其中编码表改为:
|
||||
|
||||
```cpp
|
||||
char EncodeTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
||||
```
|
||||
|
||||
编码之后你应该会得到一个16字节长的字符串,并且以"NAV"打头。
|
||||
|
||||
将16字节的字符串分成4个4字节的小块,然后用`"-"`连接就可以得到 __序列号__。
|
||||
|
||||
## 2. 激活过程
|
||||
|
||||
1. 检查用户输入的 __序列号__ 是否合法。
|
||||
|
||||
2. 在用户点击了`激活`按钮之后,Navicat会先尝试在线激活。如果失败,用户可以选择离线激活。
|
||||
|
||||
3. Navicat会使用用户输入的 __序列号__ 以及从用户电脑收集来的信息生成 __离线激活请求信息__,然后用 __Navicat激活公钥__ 加密,并将密文用Base64编码,最后得到 __请求码__。
|
||||
|
||||
4. 正常流程下,__请求码__ 应该通过可联网的电脑发送给Navicat的官方激活服务器。之后Navicat的官方激活服务器会返回一个合法的 __激活码__。
|
||||
|
||||
但现在我们使用注册机来扮演官方激活服务器的角色,只是Navicat软件里的激活公钥得换成自己的公钥:
|
||||
|
||||
1. 根据 __请求码__, 获得`"DI"`值和`"K"`值。
|
||||
|
||||
2. 用`"K"`值、用户名、组织名和`"DI"`值填写 __离线激活回复信息__。
|
||||
|
||||
3. 用自己的2048位RSA私钥加密 __离线激活回复信息__,你将会得到256字节的密文。
|
||||
|
||||
4. 用Base64编码这256字节的密文,就可以得到 __激活码__。
|
||||
|
||||
5. 在Navicat软件中填入 __激活码__ 即可完成离线激活。
|
||||
|
||||
@@ -1,389 +1,229 @@
|
||||
# Navicat Keygen
|
||||
|
||||
[中文版README](README.zh-CN.md)
|
||||
[中文版README](README.zh-CN.md)
|
||||
|
||||
This repository will tell you how Navicat offline activation works.
|
||||
This repository will tell you how Navicat offline activation works.
|
||||
|
||||
## 1. Keyword Explanation.
|
||||
[How does it work?](HOW_DOES_IT_WORK.md)
|
||||
|
||||
* __Navicat Activation Public Key__
|
||||
## How to use?
|
||||
|
||||
It is a __RSA-2048__ public key that Navicat used to encrypt or decrypt offline activation information.
|
||||
1. Download the latest release [from here](https://github.com/DoubleLabyrinth/navicat-keygen/releases).
|
||||
|
||||
It is stored in __navicat.exe__ as a kind of resource called __RCData__. The resource name is `"ActivationPubKey"`. You can see it by a kind of software [___Resource Hacker___](http://www.angusj.com/resourcehacker/). The concrete content is:
|
||||
2. Use `navicat-patcher.exe` to replace __Navicat Activation Public Key__ that is stored in `navicat.exe` or `libcc.dll`.
|
||||
|
||||
```
|
||||
navicat-patcher.exe <Navicat installation path> [RSA-2048 PEM file]
|
||||
```
|
||||
|
||||
> -----BEGIN PUBLIC KEY-----
|
||||
> MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw1dqF3SkCaAAmMzs889I
|
||||
> qdW9M2dIdh3jG9yPcmLnmJiGpBF4E9VHSMGe8oPAy2kJDmdNt4BcEygvssEfginv
|
||||
> a5t5jm352UAoDosUJkTXGQhpAWMF4fBmBpO3EedG62rOsqMBgmSdAyxCSPBRJIOF
|
||||
> R0QgZFbRnU0frj34fiVmgYiLuZSAmIbs8ZxiHPdp1oD4tUpvsFci4QJtYNjNnGU2
|
||||
> WPH6rvChGl1IRKrxMtqLielsvajUjyrgOC6NmymYMvZNER3htFEtL1eQbCyTfDmt
|
||||
> YyQ1Wt4Ot12lxf0wVIR5mcGN7XCXJRHOFHSf1gzXWabRSvmt1nrl7sW6cjxljuuQ
|
||||
> awIDAQAB
|
||||
> -----END PUBLIC KEY-----
|
||||
|
||||
If you have the corresponding private key, please tell me. I would be very appreciated for your generous.
|
||||
|
||||
__NOTICE:__
|
||||
|
||||
Start from __Navicat Premium 12.0.25__, Navicat do not load this public key from resource in `navicat.exe`. Actually the public key is stored in `libcc.dll` and encrypted. And to avoid being replaced easily, the public key is split into 5 parts:
|
||||
|
||||
The content below is discovered from `libcc.dll` of Navicat Premium x64 12.0.25 Simplified Chinese version. SHA256 value is `607e0a84c75966b00f3d12fa833e91d159e4f51ac51b6ba66f98d0c3cbefdce0`. I do not guaranteed that __offset__ value is absolutely correct in other versions. But __char string__ and __immediate values__ is highly possible to be found.
|
||||
|
||||
1. At file offset `+ 0x1A12090` in `libcc.dll`, stored as __char string__:
|
||||
|
||||
> "D75125B70767B94145B47C1CB3C0755E
|
||||
> 7CCB8825C5DCE0C58ACF944E08280140
|
||||
> 9A02472FAFFD1CD77864BB821AE36766
|
||||
> FEEDE6A24F12662954168BFA314BD950
|
||||
> 32B9D82445355ED7BC0B880887D650F5"
|
||||
|
||||
2. At file offset `+ 0x59D799` in `libcc.dll`, stored as __immediate value__ in a instruction:
|
||||
|
||||
> 0xFE 0xEA 0xBC 0x01
|
||||
|
||||
In decimal: `29158142`
|
||||
|
||||
3. At file offset `+ 0x1A11DA0` in `libcc.dll`, stored as __char string__:
|
||||
|
||||
> "E1CED09B9C2186BF71A70C0FE2F1E0AE
|
||||
> F3BD6B75277AAB20DFAF3D110F75912B
|
||||
> FB63AC50EC4C48689D1502715243A79F
|
||||
> 39FF2DE2BF15CE438FF885745ED54573
|
||||
> 850E8A9F40EE2FF505EB7476F95ADB78
|
||||
> 3B28CA374FAC4632892AB82FB3BF4715
|
||||
> FCFE6E82D03731FC3762B6AAC3DF1C3B
|
||||
> C646FE9CD3C62663A97EE72DB932A301
|
||||
> 312B4A7633100C8CC357262C39A2B3A6
|
||||
> 4B224F5276D5EDBDF0804DC3AC4B8351
|
||||
> 62BB1969EAEBADC43D2511D6E0239287
|
||||
> 81B167A48273B953378D3D2080CC0677
|
||||
> 7E8A2364F0234B81064C5C739A8DA28D
|
||||
> C5889072BF37685CBC94C2D31D0179AD
|
||||
> 86D8E3AA8090D4F0B281BE37E0143746
|
||||
> E6049CCC06899401264FA471C016A96C
|
||||
> 79815B55BBC26B43052609D9D175FBCD
|
||||
> E455392F10E51EC162F51CF732E6BB39
|
||||
> 1F56BBFD8D957DF3D4C55B71CEFD54B1
|
||||
> 9C16D458757373E698D7E693A8FC3981
|
||||
> 5A8BF03BA05EA8C8778D38F9873D62B4
|
||||
> 460F41ACF997C30E7C3AF025FA171B5F
|
||||
> 5AD4D6B15E95C27F6B35AD61875E5505
|
||||
> 449B4E"
|
||||
|
||||
4. At file offset `+ 0x59D77F` in `libcc.dll`, stored as __immediate value__ in a instruction:
|
||||
|
||||
> 0x59 0x08 0x01 0x00 (in decimal )
|
||||
|
||||
In decimal: `67673`
|
||||
|
||||
5. At file offset `+ 0x1A11D8C` in `libcc.dll`, stored as __char string__:
|
||||
|
||||
> "92933"
|
||||
|
||||
Then output encrypted public key with format `"%s%d%s%d%s"`, the order is the same as it list:
|
||||
|
||||
> D75125B70767B94145B47C1CB3C0755E7CCB8825C5DCE0C58ACF944E082801409A02472FAFFD1CD77864BB821AE36766FEEDE6A24F12662954168BFA314BD95032B9D82445355ED7BC0B880887D650F529158142E1CED09B9C2186BF71A70C0FE2F1E0AEF3BD6B75277AAB20DFAF3D110F75912BFB63AC50EC4C48689D1502715243A79F39FF2DE2BF15CE438FF885745ED54573850E8A9F40EE2FF505EB7476F95ADB783B28CA374FAC4632892AB82FB3BF4715FCFE6E82D03731FC3762B6AAC3DF1C3BC646FE9CD3C62663A97EE72DB932A301312B4A7633100C8CC357262C39A2B3A64B224F5276D5EDBDF0804DC3AC4B835162BB1969EAEBADC43D2511D6E023928781B167A48273B953378D3D2080CC06777E8A2364F0234B81064C5C739A8DA28DC5889072BF37685CBC94C2D31D0179AD86D8E3AA8090D4F0B281BE37E0143746E6049CCC06899401264FA471C016A96C79815B55BBC26B43052609D9D175FBCDE455392F10E51EC162F51CF732E6BB391F56BBFD8D957DF3D4C55B71CEFD54B19C16D458757373E698D7E693A8FC39815A8BF03BA05EA8C8778D38F9873D62B4460F41ACF997C30E7C3AF025FA171B5F5AD4D6B15E95C27F6B35AD61875E5505449B4E6767392933
|
||||
|
||||
This encrypted public key can be decrypted by my another repo: [how-does-navicat-encrypt-password](https://github.com/DoubleLabyrinth/how-does-navicat-encrypt-password), while the key used is `b'23970790'`
|
||||
|
||||
Example:
|
||||
|
||||
```cmd
|
||||
E:\GitHub>git clone https://github.com/DoubleLabyrinth/how-does-navicat-encrypt-password.git
|
||||
...
|
||||
E:\GitHub>cd how-does-navicat-encrypt-password\python3
|
||||
E:\GitHub\how-does-navicat-encrypt-password\python3>python
|
||||
Python 3.6.3 (v3.6.3:2c5fed8, Oct 3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)] on win32
|
||||
Type "help", "copyright", "credits" or "license" for more information.
|
||||
>>> from NavicatCrypto import *
|
||||
>>> cipher = Navicat11Crypto(b'23970790')
|
||||
>>> print(cipher.DecryptString('D75125B70767B94145B47C1CB3C0755E7CCB8825C5DCE0C58ACF944E082801409A02472FAFFD1CD77864BB821AE36766FEEDE6A24F12662954168BFA314BD95032B9D82445355ED7BC0B880887D650F529158142E1CED09B9C2186BF71A70C0FE2F1E0AEF3BD6B75277AAB20DFAF3D110F75912BFB63AC50EC4C48689D1502715243A79F39FF2DE2BF15CE438FF885745ED54573850E8A9F40EE2FF505EB7476F95ADB783B28CA374FAC4632892AB82FB3BF4715FCFE6E82D03731FC3762B6AAC3DF1C3BC646FE9CD3C62663A97EE72DB932A301312B4A7633100C8CC357262C39A2B3A64B224F5276D5EDBDF0804DC3AC4B835162BB1969EAEBADC43D2511D6E023928781B167A48273B953378D3D2080CC06777E8A2364F0234B81064C5C739A8DA28DC5889072BF37685CBC94C2D31D0179AD86D8E3AA8090D4F0B281BE37E0143746E6049CCC06899401264FA471C016A96C79815B55BBC26B43052609D9D175FBCDE455392F10E51EC162F51CF732E6BB391F56BBFD8D957DF3D4C55B71CEFD54B19C16D458757373E698D7E693A8FC39815A8BF03BA05EA8C8778D38F9873D62B4460F41ACF997C30E7C3AF025FA171B5F5AD4D6B15E95C27F6B35AD61875E5505449B4E6767392933'))
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw1dqF3SkCaAAmMzs889I
|
||||
qdW9M2dIdh3jG9yPcmLnmJiGpBF4E9VHSMGe8oPAy2kJDmdNt4BcEygvssEfginv
|
||||
a5t5jm352UAoDosUJkTXGQhpAWMF4fBmBpO3EedG62rOsqMBgmSdAyxCSPBRJIOF
|
||||
R0QgZFbRnU0frj34fiVmgYiLuZSAmIbs8ZxiHPdp1oD4tUpvsFci4QJtYNjNnGU2
|
||||
WPH6rvChGl1IRKrxMtqLielsvajUjyrgOC6NmymYMvZNER3htFEtL1eQbCyTfDmt
|
||||
YyQ1Wt4Ot12lxf0wVIR5mcGN7XCXJRHOFHSf1gzXWabRSvmt1nrl7sW6cjxljuuQ
|
||||
awIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
```
|
||||
|
||||
* __Request Code__
|
||||
|
||||
It is a Base64 string that represents 256-bytes-long data, while the 256-bytes-long data is the cipher text of the __offline activation information__ encrypted by __Navicat Activation Public Key__.
|
||||
|
||||
* __Offline Activation Request Information__
|
||||
|
||||
It is just a JSON-style ASCII string which contains 3 items. Respectively they are `"K"`, `"DI"` and `"P"`, which represent __snKey__, __DeviceIdentifier__ (related with your machine), __Platform__ (Appropriately speaking, it should be OS Type).
|
||||
|
||||
Like:
|
||||
> {"K": "xxxxxxxxxxxxxxxx", "DI": "yyyyyyyyyyyyy", "P": "WIN8"}
|
||||
|
||||
* __Activation Code__
|
||||
|
||||
It is a Base64 string that represents 256-bytes-long data, while the 256-bytes-long data is the cipher text of the __offline activation response information__ encrypted by __Navicat Activation Private Key__ (so far, we don't know official activation private key).
|
||||
|
||||
* __Offline Activation Response Information__
|
||||
|
||||
Just like __Offline Activation Request Information__, it is also a JSON-style ASCII string. But it contains 5 items. Respectively they are `"K"`, `"N"`, `"O"`, `"T"`, '`DI`'.
|
||||
|
||||
`"K"` and `"DI"` has the same meaning mentioned in __Offline Activation Request Information__ and must be same with the corresponding items in __Offline Activation Request Information__.
|
||||
|
||||
`"N"`, `"O"`, `"T"` represent __Name__, __Organization__, __Time__ respectively. __Name__ and __Organization__ are string and the type of __Time__ can be string or integer (Thanks for discoveries from @Wizr, issue #10).
|
||||
|
||||
`"T"` can be omitted.
|
||||
|
||||
* __snKey__
|
||||
|
||||
It is a 4-block-long string, while every block is 4-chars-long.
|
||||
|
||||
__snKey__ is generated by 10-bytes-long data. In order to explain it easily, I use __uint8_t data[10]__ to represent the 10-bytes-long data.
|
||||
|
||||
1. __data[0]__ and __data[1]__ must be `0x68` and `0x2A` respectively.
|
||||
|
||||
These two bytes are Naivcat signature number.
|
||||
|
||||
2. __data[2]__, __data[3]__ and __data[4]__ can be any byte. Just set them whatever you want.
|
||||
|
||||
3. __data[5]__ and __data[6]__ are related with your Navicat product language.
|
||||
|
||||
| Language | data[5] | data[6] | Discoverer |
|
||||
|------------|-----------|-----------|-----------------|
|
||||
| English | 0xAC | 0x88 | |
|
||||
| 简体中文 | 0xCE | 0x32 | |
|
||||
| 繁體中文 | 0xAA | 0x99 | |
|
||||
| 日本語 | 0xAD | 0x82 | @dragonflylee |
|
||||
| Polski | 0xBB | 0x55 | @dragonflylee |
|
||||
| Español | 0xAE | 0x10 | @dragonflylee |
|
||||
| Français | 0xFA | 0x20 | @Deltafox79 |
|
||||
| Deutsch | 0xB1 | 0x60 | @dragonflylee |
|
||||
| 한국어 | 0xB5 | 0x60 | @dragonflylee |
|
||||
| Русский | 0xEE | 0x16 | @dragonflylee |
|
||||
| Português | 0xCD | 0x49 | @dragonflylee |
|
||||
|
||||
According to symbol information in __Navicat 12 for Mac x64__, these two bytes are product language signature.
|
||||
|
||||
4. __data[7]__ represents Navicat product ID. (Thanks @dragonflylee and @Deltafox79)
|
||||
|
||||
|Product Name |Enterprise|Standard|Educational|Essentials|
|
||||
|---------------------|:--------:|:------:|:---------:|:--------:|
|
||||
|Navicat Report Viewer|0x0B | | | |
|
||||
|Navicat Data Modeler | |0x47 |0x4A | |
|
||||
|Navicat Premium |0x65 | |0x66 |0x67 |
|
||||
|Navicat MySQL |0x68 |0x69 |0x6A |0x6B |
|
||||
|Navicat PostgreSQL |0x6C |0x6D |0x6E |0x6F |
|
||||
|Navicat Oracle |0x70 |0x71 |0x72 |0x73 |
|
||||
|Navicat SQL Server |0x74 |0x75 |0x76 |0x77 |
|
||||
|Navicat SQLite |0x78 |0x79 |0x7A |0x7B |
|
||||
|Navicat MariaDB |0x7C |0x7D |0x7E |0x7F |
|
||||
|Navicat MongoDB |0x80 |0x81 |0x82 | |
|
||||
|
||||
5. High 4 bits of __data[8]__ represents __major version number__. Low 4 bits is unknown, but we can use it to delay activation deadline. Possible value is `0000` or `0001`.
|
||||
|
||||
__Example:__
|
||||
|
||||
For __Navicat 12 x64__: High 4 bits must be `1100`, which is the binary of number `12`.
|
||||
For __Navicat 11 x64__: High 4 bits must be `1011`, which is the binary of number `11`.
|
||||
|
||||
6. __data[9]__ is unknown, but you can set it `0xFD` or `0xFC` or `0xFB` if you want to use __not-for-resale license__.
|
||||
|
||||
According to symbol information in __Navicat 12 for Mac x64__ version:
|
||||
|
||||
* `0xFB` is __Not-For-Resale-30-days__ license.
|
||||
* `0xFC` is __Not-For-Resale-90-days__ license.
|
||||
* `0xFD` is __Not-For-Resale-365-days__ license.
|
||||
* `0xFE` is __Not-For-Resale__ license.
|
||||
* `0xFF` is __Site__ license.
|
||||
|
||||
-----------------
|
||||
|
||||
After that. Navicat use __DES__ with __ECB mode__ to encrypt the last 8 bytes which are from __data[2]__ to __data[9]__.
|
||||
|
||||
The DES key is:
|
||||
|
||||
```cpp
|
||||
unsigned char DESKey = { 0x64, 0xAD, 0xF3, 0x2F, 0xAE, 0xF2, 0x1A, 0x27 };
|
||||
```
|
||||
|
||||
Then encode the 10-bytes-long data: __(Use Base32 encode if you just want a conclusion.)__
|
||||
|
||||
1. Regard __uint8_t data[10]__ as a 80-bits-long data.
|
||||
|
||||
If __uint8_t data[10]__ starts with `0x68` and `0x2A`, so the 80-bits-long data is `01011000 00101010......`
|
||||
|
||||
2. Divide the 80-bits-long data as 16 5-bits-long blocks.
|
||||
|
||||
If __uint8_t data[10]__ starts with `0x68` and `0x2A`, so the 80-bits-long data is `01011`, `00000`, `10101`, `0....`, ...
|
||||
|
||||
3. The values in every block are less than 32. Map them by a encode-table:
|
||||
|
||||
```cpp
|
||||
char EncodeTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
||||
```
|
||||
|
||||
Then you will get a 16-char-long string.
|
||||
|
||||
If __uint8_t data[10]__ starts with `0x68` and `0x2A`, after encoded, it should starts with `"N"`, `"A"`, `"V"`.
|
||||
|
||||
4. Divide the 16-char-long string to four 4-chars-long blocks, then you get __snKey__.
|
||||
|
||||
## 3. Activation Process
|
||||
|
||||
1. Check whether __snKey__ that user inputs is legal.
|
||||
|
||||
2. After user clicks `Activate`, Navicat will start online activation first. If fails, users can choose offline activation.
|
||||
|
||||
3. Navicat will use the __snKey__ that user inputs and some information collected from user's machine to generate __Offline Activation Request Information__, then encrypt it by __Navicat Activation Public Key__ and return Base64-encoded string as __Request Code__.
|
||||
|
||||
4. In legal way, the __Request Code__ should be sent to Navicat official activation server by a Internet-accessible computer. And Navicat official activation server will return a legal __Activation Code__.
|
||||
|
||||
But now, we use keygen to play the official activation server's role.
|
||||
|
||||
1. According to the __Request Code__, Get `"DI"` value and `"K"` value.
|
||||
|
||||
2. Fill __Offline Activation Response Information__ with `"K"` value, name, organization name and `"DI"` value.
|
||||
|
||||
3. Encrypt __Offline Activation Response Information__ by __Navicat Activation Private Key__ and you will get 256-byte-long data.
|
||||
|
||||
4. Encode 256-byte-long data by Base64. The result is __Activation Code__.
|
||||
|
||||
5. Input __Activation Code__, then offline activation is done.
|
||||
|
||||
## 4. How to use
|
||||
1. Download the latest release [from here](https://github.com/DoubleLabyrinth/navicat-keygen/releases).
|
||||
|
||||
2. Replace __Navicat Activation Public Key__ in `navicat.exe` or `libcc.dll`.
|
||||
|
||||
Example:
|
||||
|
||||
|
||||
```bash
|
||||
C:\Users\DoubleSine\Github\navicat-keygen\x64\Release>navicat-patcher.exe "C:\Program Files\PremiumSoft\Navicat Premium 12" RegPrivateKey.pem
|
||||
Target has been found: navicat.exe
|
||||
Solution0 has been done successfully.
|
||||
|
||||
Keyword0 has been found: offset = +0x02048200.
|
||||
Keyword1 has been found: offset = +0x006C4E29.
|
||||
Keyword2 has been found: offset = +0x02047F10.
|
||||
Keyword3 has been found: offset = +0x006C4E0F.
|
||||
Keyword4 has been found: offset = +0x02047F04.
|
||||
|
||||
@Offset +0x02048200, write string:
|
||||
"D75125B70767B94145B47C1CB3C0755E7CCB8825C5DCE0C58ACF944E082801409A02472FAFFD1CD77864BB821AE36766FEEDE6A24F12662954168BFA314BD95032B9D82445355ED7784ADAC1C58775D2"
|
||||
|
||||
@Offset +0x006C4E29, write uint32_t:
|
||||
0x0520738A
|
||||
|
||||
@Offset +0x02047F10, write string:
|
||||
"20EEA059669FE4E949F414710A6C11CF68B5318B445D2D0CA85471E9DC382F271E974315F2F3645C2613BF60669584CF0A7531B1E5D2D281097E32A6B17286E8A9BDD06A17A036BC8949C9069CA3A166C251D325A7EAF81DB272CF4E277CC487D6BACB83C1059BBC0D45F49CBB6EA2C0E8033039CA575A939C8FF705FFA1FCA9DD53FD10447EE8D2F48128298E5DAB483F7A1500C455AFE33BB7FB280C39686CC45C7EC8C024EBF1089040D6636FF02E0E2A61092168A5CB105DBF3F5C6EB5C10D7392A46254B6E34DD4365F778ED199A52C6AB931416453CB8A677C90A6674BA5D546B25CDEC9C2E0B067729A6067FB1106B3BF7BBD56B888B5321484779570040B2095CD410D3B33F77BCFC9C24CA5A60003E342F110D35AA4714BFC8B3D9840BB3C8C286C5E353D5DEC4351A27E6E403AED2A21BBD0EA4194FB65B37F301A2E86BF9E9F8BBBFAA2400410ABC7833B3CCAAC66F27F873990E2D97BB36A70A5C9E4E3647C3AD0FAA716820A0BDC15CA8D7392"
|
||||
|
||||
@Offset +0x006C4E0F, write uint32_t:
|
||||
0x00004708
|
||||
|
||||
@Offset +0x02047F04, write string:
|
||||
"64308"
|
||||
|
||||
Solution1 has been done successfully.
|
||||
|
||||
```
|
||||
|
||||
3. Then in console:
|
||||
|
||||
```bash
|
||||
C:\Users\DoubleSine\Github\navicat-keygen\x64\Release>navicat-keygen.exe RegPrivateKey.pem
|
||||
```
|
||||
|
||||
You will be asked to select Navicat product, language and input major version number. After that an randomly generated __snKey__ will be generated.
|
||||
|
||||
__Example:__
|
||||
|
||||
```bash
|
||||
C:\Users\DoubleSine\Github\navicat-keygen\x64\Release>navicat-keygen.exe RegPrivateKey.pem
|
||||
Select Navicat product:
|
||||
0. DataModeler
|
||||
1. Premium
|
||||
2. MySQL
|
||||
3. PostgreSQL
|
||||
4. Oracle
|
||||
5. SQLServer
|
||||
6. SQLite
|
||||
7. MariaDB
|
||||
8. MongoDB
|
||||
9. ReportViewer
|
||||
|
||||
(input index)> 1
|
||||
|
||||
Select product language:
|
||||
0. English
|
||||
1. Simplified Chinese
|
||||
2. Traditional Chinese
|
||||
3. Japanese
|
||||
4. Polish
|
||||
5. Spanish
|
||||
6. French
|
||||
7. German
|
||||
8. Korean
|
||||
9. Russian
|
||||
10. Portuguese
|
||||
|
||||
(input index)> 0
|
||||
|
||||
(input major version number)> 12
|
||||
|
||||
Serial number:
|
||||
NAVI-2ORL-MJQC-7WFO
|
||||
|
||||
Your name:
|
||||
```
|
||||
|
||||
You can use this __snKey__ to activate your Navicat preliminarily.
|
||||
* `<Navicat installation path>`: The full path to Navicat installation folder.
|
||||
|
||||
Then you will be asked to input `Your name` and `Your organization`. Just set them whatever you want, but not too long.
|
||||
__This parameter must be specified.__
|
||||
|
||||
* `[RSA-2048 PEM file]`: The full path or relative path to a RSA-2048 private key file.
|
||||
|
||||
__Example:__
|
||||
__This parameter is optional.__ If not specified, `navicat-patcher.exe` will generate a new RSA-2048 private key file `RegPrivateKey.pem` at current directory.
|
||||
|
||||
```bash
|
||||
Your name: DoubleLabyrinth
|
||||
Your organization: DoubleLabyrinth
|
||||
Input request code (in Base64), input empty line to end:
|
||||
```
|
||||
__Example: (in cmd.exe)__
|
||||
|
||||
```
|
||||
navicat-patcher.exe "C:\Program Files\PremiumSoft\Navicat Premium 12"
|
||||
```
|
||||
|
||||
It has been tested on __Navicat Premium 12.1.12 Simplified Chinese version__. The following is an example of output.
|
||||
|
||||
```
|
||||
***************************************************
|
||||
* Navicat Patcher by @DoubleLabyrinth *
|
||||
* Release date: Jan 19 2019 *
|
||||
***************************************************
|
||||
|
||||
Press Enter to continue or Ctrl + C to abort.
|
||||
|
||||
MESSAGE: PatchSolution0 will be omitted.
|
||||
|
||||
MESSAGE: PatchSolution3: Keywords[0] has been found:
|
||||
Relative Machine Code Offset = +0x0000000001644a08
|
||||
Relative Machine Code RVA = +0x0000000001645608
|
||||
Patch Offset = +0x00000000023d56e4
|
||||
Patch Size = 3 byte(s)
|
||||
...
|
||||
...
|
||||
...
|
||||
MESSAGE: PatchSolution3: Keywords[110] has been found:
|
||||
Relative Machine Code Offset = +0x000000000165155e
|
||||
Relative Machine Code RVA = +0x000000000165215e
|
||||
Patch Offset = +0x0000000001651561
|
||||
Patch Size = 1 byte(s)
|
||||
|
||||
MESSAGE: PatchSolution2 will be omitted.
|
||||
|
||||
MESSAGE: PatchSolution1: Keywords[0] has been found: offset = +0x021f7390.
|
||||
MESSAGE: PatchSolution1: Keywords[1] has been found: offset = +0x0074bd39.
|
||||
MESSAGE: PatchSolution1: Keywords[2] has been found: offset = +0x021f70a0.
|
||||
MESSAGE: PatchSolution1: Keywords[3] has been found: offset = +0x0074bd1f.
|
||||
MESSAGE: PatchSolution1: Keywords[4] has been found: offset = +0x021f708c.
|
||||
|
||||
MESSAGE: Generating new RSA private key, it may take a long time.
|
||||
MESSAGE: New RSA private key has been saved to RegPrivateKey.pem.
|
||||
|
||||
Your RSA public key:
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsWnV5hQxlXvDA3Ad4k5N
|
||||
ZLz4cO+iGEPegSovIDcwTo097I+0pXYKPTVl+0iKC5JtJRObb4Xx9yK9gGwqkcxo
|
||||
o6WzKq0xY1jz7X6obxwlQCNse3Os1wr0rIY0UzP1dCpkW/5MwGbFxiB6PEVqkzmJ
|
||||
CmHBzZDRu/jAuL1nyoiGnUStqwENNYhyl4k7r8AiJkBZGMOCrj6v0JfgNna25Ce6
|
||||
QCFojlY4dkYQ5/7njQ3qpLwMeLEXEysMW3aUScSB68/vsHnB4C0fIkwfEPYZ/AC5
|
||||
AqbWHVbNmveB3rjV+tZZxXcLE8ArgKh1Gs+2VtnL09gwHm6WcpyPZ42G6tMDjWyw
|
||||
1wIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
|
||||
******************************************
|
||||
* PatchSulution3 *
|
||||
******************************************
|
||||
@ +023d56e4: 4D 49 49 ---> 4D 49 49
|
||||
@ +01644a63: 42 49 ---> 42 49
|
||||
@ +01644a68: 6A ---> 6A
|
||||
@ +01644ace: 41 ---> 41
|
||||
...
|
||||
...
|
||||
...
|
||||
@ +023d58d4: 36 63 6A ---> 47 36 74
|
||||
@ +023d58d8: 78 6C 6A 75 75 51 61 ---> 4D 44 6A 57 79 77 31
|
||||
@ +023d58e8: 77 49 44 41 ---> 77 49 44 41
|
||||
@ +0165155c: 51 41 ---> 51 41
|
||||
@ +01651561: 42 ---> 42
|
||||
|
||||
******************************************
|
||||
* PatchSulution1 *
|
||||
******************************************
|
||||
@ +0x021f7390
|
||||
Previous:
|
||||
+0x00000000021F7390 44 37 35 31 32 35 42 37 30 37 36 37 42 39 34 31 D75125B70767B941
|
||||
+0x00000000021F73A0 34 35 42 34 37 43 31 43 42 33 43 30 37 35 35 45 45B47C1CB3C0755E
|
||||
+0x00000000021F73B0 37 43 43 42 38 38 32 35 43 35 44 43 45 30 43 35 7CCB8825C5DCE0C5
|
||||
...
|
||||
...
|
||||
...
|
||||
|
||||
@ +0x021f708c
|
||||
Previous:
|
||||
+0x00000000021F7080 31 32 32 35 4f 45 29 2e 00 00 00 00 39 32 39 33 1225OE).....9293
|
||||
+0x00000000021F7090 33 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3...............
|
||||
After:
|
||||
+0x00000000021F7080 31 32 32 35 4f 45 29 2e 00 00 00 00 32 37 45 38 1225OE).....27E8
|
||||
+0x00000000021F7090 45 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 E...............
|
||||
|
||||
MESSAGE: Patch has been done successfully.
|
||||
```
|
||||
|
||||
3. Then use `navicat-keygen.exe` to generate __snKey__ and __Activation Code__
|
||||
|
||||
```
|
||||
navicat-keygen.exe <-bin|-text> [-adv] <RSA-2048 PrivateKey(PEM file)>
|
||||
```
|
||||
|
||||
* `<-bin|-text>`: Must be `-bin` or `-text`.
|
||||
|
||||
If `-bin` is specified, `navicat-keygen.exe` will finally generate `license_file`. It is used for Navicat old activation method only.
|
||||
|
||||
If `-text` is specified, `navicat-keygen.exe` will finally generate a Base64-style string which is __Activation Code__. It is used for Navicat new activation method.
|
||||
|
||||
__This parameter must be specified.__
|
||||
|
||||
* `[-adv]`: Enable advanced mode.
|
||||
|
||||
__This parameter is optional.__ If specified, `navicat-keygen.exe` will ask you input Navicat product ID number, language signature numbers. It is for future use generally.
|
||||
|
||||
* `<RSA-2048 PrivateKey(PEM file)>`: The full path or relative path to a RSA-2048 private key file.
|
||||
|
||||
After that, you will be asked to input the request code. Now __DO NOT CLOSE KEYGEN__.
|
||||
__This parameter must be specified.__
|
||||
|
||||
4. Disconnect network and open Navicat. Find and click `Registration`. Fill `Registration Key` by __snKey__ that keygen gave. Then click `Activate`.
|
||||
__Example: (in cmd.exe)__
|
||||
|
||||
5. Generally online activation will failed and Navicat will ask you do `Manual Activation`, just choose it.
|
||||
```bash
|
||||
navicat-keygen.exe -text .\RegPrivateKey.pem
|
||||
```
|
||||
|
||||
6. Copy your request code and paste it in keygen. Input empty line to tell keygen that your input ends.
|
||||
You will be asked to select Navicat product, language and input major version number. After that an randomly generated __snKey__ will be given.
|
||||
|
||||
__Example:__
|
||||
```
|
||||
Select Navicat product:
|
||||
0. DataModeler
|
||||
1. Premium
|
||||
2. MySQL
|
||||
3. PostgreSQL
|
||||
4. Oracle
|
||||
5. SQLServer
|
||||
6. SQLite
|
||||
7. MariaDB
|
||||
8. MongoDB
|
||||
9. ReportViewer
|
||||
|
||||
```bash
|
||||
Your name: DoubleLabyrinth
|
||||
Your organization: DoubleLabyrinth
|
||||
Input request code (in Base64), input empty line to end:
|
||||
J517hWX/29aQMITp5UfS/FarX6q8pFKmW1Cl7Nt2UpvmVxhZDn5YBdPw/htDsBbXacNpLtorxfZM
|
||||
Jxv/SZMqHsr7/JqexaaAEfzn5mo6zpatcSRArFoQh2h9IcnjRqziZ8yihkMUesKgsWXvVXMEYk7u
|
||||
D1rc/GhzTf6/2kn0gTKRAlJGsxt+e1p6SOhPuMyzt3AyNvJ2s0o607Nub7vC37FOJF69jN1nOvej
|
||||
uy3bmr2HSPFsh10WqUUYi6F1lzzYIq6nDjQ5CeKrCT2jPfrhoFtRbwJyYDxQOxU/adrm1bg8VjrK
|
||||
XNGeKS67R1nrbBM03IKzPP3pxEGFut4gZdskRw==
|
||||
(Input index)> 1
|
||||
|
||||
Request Info:
|
||||
{"K":"NAVI2ORLMJQC7WFO", "DI":"Y2eJk9vrvfGudPG7Mbdn", "P":"WIN 8"}
|
||||
Select product language:
|
||||
0. English
|
||||
1. Simplified Chinese
|
||||
2. Traditional Chinese
|
||||
3. Japanese
|
||||
4. Polish
|
||||
5. Spanish
|
||||
6. French
|
||||
7. German
|
||||
8. Korean
|
||||
9. Russian
|
||||
10. Portuguese
|
||||
|
||||
Response Info:
|
||||
{"K":"NAVI2ORLMJQC7WFO","DI":"Y2eJk9vrvfGudPG7Mbdn","N":"DoubleLabyrinth","O":"DoubleLabyrinth","T":1534251096}
|
||||
(Input index)> 1
|
||||
|
||||
License:
|
||||
iFvqOkwsVq/Wutw/hELC5dyweDahl2v8R3bMWcNXS/V49CjpaDEJIHtRLddu/ldg
|
||||
WVGdwdh3aHVJ5k8I6RkUicDvZJH2vLn3o5O9Q/A5ThED0AoYnwu0DLa1gEUlRO68
|
||||
4+uXwo1nZ+xtjLOSxrVh+fLkcvKtd5RDgHS5957qUwjoYBiuePGomtt9mF4NtfaF
|
||||
E7pnfP/OGp8xtWdUfGZ1fESWttKcVXcmOpyF4uTWtluUhFHRk+ZueST/ETyaSx33
|
||||
Kv/zSLBbK8KaVqS2sh5WBs8xVaYxDV08EC8uCCp1euTFOPG5nlrcf7iyILsh6I67
|
||||
xfGRliXvM67jvsxqD200fg==
|
||||
(Input major version number, range: 0 ~ 15, default: 12)> 12
|
||||
|
||||
```
|
||||
Serial number:
|
||||
NAVO-2ORP-IN5A-GQEE
|
||||
|
||||
Your name:
|
||||
```
|
||||
|
||||
You can use this __snKey__ to activate your Navicat preliminarily.
|
||||
|
||||
Then you will be asked to input `Your name` and `Your organization`. Just set them whatever you want, but not too long.
|
||||
|
||||
```
|
||||
Your name: DoubleLabyrinth
|
||||
Your organization: DoubleLabyrinth
|
||||
Input request code (in Base64), input empty line to end:
|
||||
```
|
||||
|
||||
After that, you will be asked to input the request code. Now __DO NOT CLOSE KEYGEN__.
|
||||
|
||||
4. __Disconnect your network__ and open Navicat. Find and click `Registration`. Fill `Registration Key` by __snKey__ that the keygen gave and click `Activate`.
|
||||
|
||||
5. Generally online activation will failed and Navicat will ask you do `Manual Activation`, just choose it.
|
||||
|
||||
6. Copy your request code and paste it in the keygen. Input empty line to tell the keygen that your input ends.
|
||||
|
||||
```
|
||||
Your name: DoubleLabyrinth
|
||||
Your organization: DoubleLabyrinth
|
||||
|
||||
Input request code (in Base64), input empty line to end:
|
||||
t2U+0yfE2FfnbjyhCXa0lglZOHu9Ntc3qyGiPbR6xb1QoU63/9BVfdaCq0blwVycXPyT/Vqw5joIKdM5oCRR/afCPM7iRcyhQMAnvqwc+AOKCqayVV+SqKLvtR/AbREI12w++PQ6Ewfs4A8PgB8OJ9G0jKt6Q/iJRblqi2WWw9mwy+YHcYYh3UAfygTnyj/xl+MzRymbY0lkus+6LPtpDecVsFFhM7F32Ee1QPwISko7bAkHOtkt+joPfYDdn9PDGZ4HEmeLvH6UqZCXkzgaAfynB7cQZFEkId8FsW2NGkbpM7wB2Hi3fNFgOIjutTprixTdbpFKn4w6gGc28ve23A==
|
||||
|
||||
Request Info:
|
||||
{"K":"NAVO2ORPIN5AGQEE", "DI":"R91j6WyMhxHznAKSxxxx", "P":"WIN"}
|
||||
|
||||
Response Info:
|
||||
{"K":"NAVO2ORPIN5AGQEE","DI":"R91j6WyMhxHznAKSxxxx","N":"DoubleLabyrinth","O":"DoubleLabyrinth","T":1547826060}
|
||||
|
||||
License:
|
||||
lRF18o+ZhBphyN0U5kFLHtAAGGXuvhqOcxNuvAk4dJcGeR0ISuw74mQvAfdNjv0T
|
||||
I5NZFzqIJvrzM0XeR88q+3kmZkECuxwwWHP3zzDPhPiylcTV4DoGZ1tfoViUSYQc
|
||||
LgXG0Fl7koZeP61YOKQ8GfX+Xk2ZTM64bYaF7NlhonM+GQUJCCF2JThmrP921t2p
|
||||
b/E5pV6fLOYMM13881ZQcQcltMNVDZn4lzgzKRFFxCQFaTl6fJMHZdYVmICQTHtI
|
||||
sNaym0zduc8/cv34mgJ+7NseXmsEPCdjrZ59wgfPsLhZLXqtfxi5hGWw4NMa3Sb2
|
||||
UI8dzqFzRp/hSDEM0mEqiA==
|
||||
```
|
||||
|
||||
7. Finally, you will get __Activation Code__ which looks like a Base64 string. Just copy it and paste it in Navicat `Manual Activation` window, then click `Activate`. If nothing wrong, activation should be done successfully.
|
||||
|
||||
7. Finally, you will get activation code which looks like a Base64 string. Just copy it and paste it in Navicat `Manual Activation` window, then click `Activate`. If nothing wrong, activation should be done successfully.
|
||||
|
||||
+206
-371
@@ -1,392 +1,227 @@
|
||||
# Navicat Keygen
|
||||
|
||||
这份repo将会告诉你Navicat是怎么完成离线激活的。
|
||||
这份repo将会告诉你Navicat是怎么完成离线激活的。
|
||||
|
||||
## 1. 关键词解释.
|
||||
[注册机是怎么工作的?](HOW_DOES_IT_WORK.zh-CN.md)
|
||||
|
||||
* __Navicat激活公钥__
|
||||
## 如何使用这个注册机
|
||||
|
||||
这是一个2048位的RSA公钥,Navicat使用这个公钥来完成相关激活信息的加密和解密。
|
||||
1. [从这里](https://github.com/DoubleLabyrinth/navicat-keygen/releases)下载最新的release。
|
||||
|
||||
这个公钥被作为 __RCData__ 类型的资源储存在 __navicat.exe__ 当中。资源名为`"ActivationPubKey"`。你可以使用一个叫[Resource Hacker](http://www.angusj.com/resourcehacker/)的软件来查看它。这个公钥的具体内容为:
|
||||
2. 使用`navicat-patcher.exe`替换掉`navicat.exe`和`libcc.dll`里的Navicat激活公钥。
|
||||
|
||||
> -----BEGIN PUBLIC KEY-----
|
||||
> MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw1dqF3SkCaAAmMzs889I
|
||||
> qdW9M2dIdh3jG9yPcmLnmJiGpBF4E9VHSMGe8oPAy2kJDmdNt4BcEygvssEfginv
|
||||
> a5t5jm352UAoDosUJkTXGQhpAWMF4fBmBpO3EedG62rOsqMBgmSdAyxCSPBRJIOF
|
||||
> R0QgZFbRnU0frj34fiVmgYiLuZSAmIbs8ZxiHPdp1oD4tUpvsFci4QJtYNjNnGU2
|
||||
> WPH6rvChGl1IRKrxMtqLielsvajUjyrgOC6NmymYMvZNER3htFEtL1eQbCyTfDmt
|
||||
> YyQ1Wt4Ot12lxf0wVIR5mcGN7XCXJRHOFHSf1gzXWabRSvmt1nrl7sW6cjxljuuQ
|
||||
> awIDAQAB
|
||||
> -----END PUBLIC KEY-----
|
||||
```
|
||||
navicat-patcher.exe <Navicat installation path> [RSA-2048 PEM file]
|
||||
```
|
||||
|
||||
如果您有相应的私钥并乐意公开的话欢迎联系我,我将非常感谢您的慷慨。
|
||||
|
||||
__注意:__
|
||||
|
||||
从 __Navicat Premium 12.0.25__ 开始,Navicat不再从`navicat.exe`的资源中加载私钥。事实上,公钥转为从`libcc.dll`中加载,并且已经被加密。与此同时,为了防止被轻松地替换,加密的公钥被分到5个地方储存:
|
||||
|
||||
以下内容是从 __Navicat Premium x64 12.0.25 简体中文版__ 的`libcc.dll`中发现的,`libcc.dll`的SHA256值为`607e0a84c75966b00f3d12fa833e91d159e4f51ac51b6ba66f98d0c3cbefdce0`。我不保证在Navicat的其他版本中相关偏移量和下述的相同,但相关的 __字符串__ 以及 __立即数__ 是很可能找得到的。
|
||||
|
||||
1. 在`libcc.dll`中,文件偏移量`+0x1A12090`的地方,储存了加密公钥的第一部分,以 __字符串__ 的形式储存:
|
||||
|
||||
> "D75125B70767B94145B47C1CB3C0755E
|
||||
> 7CCB8825C5DCE0C58ACF944E08280140
|
||||
> 9A02472FAFFD1CD77864BB821AE36766
|
||||
> FEEDE6A24F12662954168BFA314BD950
|
||||
> 32B9D82445355ED7BC0B880887D650F5"
|
||||
|
||||
2. 在`libcc.dll`中,文件偏移量`+0x59D799`的地方,储存了加密公钥的第二部分,以 __立即数__ 的形式储存在一条指令中:
|
||||
|
||||
> 0xFE 0xEA 0xBC 0x01
|
||||
|
||||
相应十进制为: `29158142`
|
||||
|
||||
3. 在`libcc.dll`中,文件偏移量`+0x1A11DA0`的地方,储存了加密公钥的第三部分,以 __字符串__ 的形式储存:
|
||||
|
||||
> "E1CED09B9C2186BF71A70C0FE2F1E0AE
|
||||
> F3BD6B75277AAB20DFAF3D110F75912B
|
||||
> FB63AC50EC4C48689D1502715243A79F
|
||||
> 39FF2DE2BF15CE438FF885745ED54573
|
||||
> 850E8A9F40EE2FF505EB7476F95ADB78
|
||||
> 3B28CA374FAC4632892AB82FB3BF4715
|
||||
> FCFE6E82D03731FC3762B6AAC3DF1C3B
|
||||
> C646FE9CD3C62663A97EE72DB932A301
|
||||
> 312B4A7633100C8CC357262C39A2B3A6
|
||||
> 4B224F5276D5EDBDF0804DC3AC4B8351
|
||||
> 62BB1969EAEBADC43D2511D6E0239287
|
||||
> 81B167A48273B953378D3D2080CC0677
|
||||
> 7E8A2364F0234B81064C5C739A8DA28D
|
||||
> C5889072BF37685CBC94C2D31D0179AD
|
||||
> 86D8E3AA8090D4F0B281BE37E0143746
|
||||
> E6049CCC06899401264FA471C016A96C
|
||||
> 79815B55BBC26B43052609D9D175FBCD
|
||||
> E455392F10E51EC162F51CF732E6BB39
|
||||
> 1F56BBFD8D957DF3D4C55B71CEFD54B1
|
||||
> 9C16D458757373E698D7E693A8FC3981
|
||||
> 5A8BF03BA05EA8C8778D38F9873D62B4
|
||||
> 460F41ACF997C30E7C3AF025FA171B5F
|
||||
> 5AD4D6B15E95C27F6B35AD61875E5505
|
||||
> 449B4E"
|
||||
|
||||
4. 在`libcc.dll`中,文件偏移量`+0x59D77F`的地方,储存了加密公钥的第四部分,以 __立即数__ 的形式储存在一条指令中:
|
||||
|
||||
> 0x59 0x08 0x01 0x00
|
||||
|
||||
相应十进制为: `67673`
|
||||
|
||||
5. 在`libcc.dll`中,文件偏移量`+0x1A11D8C`的地方,储存了加密公钥的第五部分,以 __字符串__ 的形式储存:
|
||||
|
||||
> "92933"
|
||||
|
||||
这五部分按照`"%s%d%s%d%s"`的形式输出则为加密的公钥,顺序和上述的顺序相同,具体的输出为:
|
||||
|
||||
> D75125B70767B94145B47C1CB3C0755E7CCB8825C5DCE0C58ACF944E082801409A02472FAFFD1CD77864BB821AE36766FEEDE6A24F12662954168BFA314BD95032B9D82445355ED7BC0B880887D650F529158142E1CED09B9C2186BF71A70C0FE2F1E0AEF3BD6B75277AAB20DFAF3D110F75912BFB63AC50EC4C48689D1502715243A79F39FF2DE2BF15CE438FF885745ED54573850E8A9F40EE2FF505EB7476F95ADB783B28CA374FAC4632892AB82FB3BF4715FCFE6E82D03731FC3762B6AAC3DF1C3BC646FE9CD3C62663A97EE72DB932A301312B4A7633100C8CC357262C39A2B3A64B224F5276D5EDBDF0804DC3AC4B835162BB1969EAEBADC43D2511D6E023928781B167A48273B953378D3D2080CC06777E8A2364F0234B81064C5C739A8DA28DC5889072BF37685CBC94C2D31D0179AD86D8E3AA8090D4F0B281BE37E0143746E6049CCC06899401264FA471C016A96C79815B55BBC26B43052609D9D175FBCDE455392F10E51EC162F51CF732E6BB391F56BBFD8D957DF3D4C55B71CEFD54B19C16D458757373E698D7E693A8FC39815A8BF03BA05EA8C8778D38F9873D62B4460F41ACF997C30E7C3AF025FA171B5F5AD4D6B15E95C27F6B35AD61875E5505449B4E6767392933
|
||||
|
||||
这个加密的公钥可以用我的另外一个repo([how-does-navicat-encrypt-password](https://github.com/DoubleLabyrinth/how-does-navicat-encrypt-password))解密,其中密钥为`b'23970790'`。
|
||||
|
||||
例如:
|
||||
|
||||
```cmd
|
||||
E:\GitHub>git clone https://github.com/DoubleLabyrinth/how-does-navicat-encrypt-password.git
|
||||
...
|
||||
E:\GitHub>cd how-does-navicat-encrypt-password\python3
|
||||
E:\GitHub\how-does-navicat-encrypt-password\python3>python
|
||||
Python 3.6.3 (v3.6.3:2c5fed8, Oct 3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)] on win32
|
||||
Type "help", "copyright", "credits" or "license" for more information.
|
||||
>>> from NavicatCrypto import *
|
||||
>>> cipher = Navicat11Crypto(b'23970790')
|
||||
>>> print(cipher.DecryptString('D75125B70767B94145B47C1CB3C0755E7CCB8825C5DCE0C58ACF944E082801409A02472FAFFD1CD77864BB821AE36766FEEDE6A24F12662954168BFA314BD95032B9D82445355ED7BC0B880887D650F529158142E1CED09B9C2186BF71A70C0FE2F1E0AEF3BD6B75277AAB20DFAF3D110F75912BFB63AC50EC4C48689D1502715243A79F39FF2DE2BF15CE438FF885745ED54573850E8A9F40EE2FF505EB7476F95ADB783B28CA374FAC4632892AB82FB3BF4715FCFE6E82D03731FC3762B6AAC3DF1C3BC646FE9CD3C62663A97EE72DB932A301312B4A7633100C8CC357262C39A2B3A64B224F5276D5EDBDF0804DC3AC4B835162BB1969EAEBADC43D2511D6E023928781B167A48273B953378D3D2080CC06777E8A2364F0234B81064C5C739A8DA28DC5889072BF37685CBC94C2D31D0179AD86D8E3AA8090D4F0B281BE37E0143746E6049CCC06899401264FA471C016A96C79815B55BBC26B43052609D9D175FBCDE455392F10E51EC162F51CF732E6BB391F56BBFD8D957DF3D4C55B71CEFD54B19C16D458757373E698D7E693A8FC39815A8BF03BA05EA8C8778D38F9873D62B4460F41ACF997C30E7C3AF025FA171B5F5AD4D6B15E95C27F6B35AD61875E5505449B4E6767392933'))
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw1dqF3SkCaAAmMzs889I
|
||||
qdW9M2dIdh3jG9yPcmLnmJiGpBF4E9VHSMGe8oPAy2kJDmdNt4BcEygvssEfginv
|
||||
a5t5jm352UAoDosUJkTXGQhpAWMF4fBmBpO3EedG62rOsqMBgmSdAyxCSPBRJIOF
|
||||
R0QgZFbRnU0frj34fiVmgYiLuZSAmIbs8ZxiHPdp1oD4tUpvsFci4QJtYNjNnGU2
|
||||
WPH6rvChGl1IRKrxMtqLielsvajUjyrgOC6NmymYMvZNER3htFEtL1eQbCyTfDmt
|
||||
YyQ1Wt4Ot12lxf0wVIR5mcGN7XCXJRHOFHSf1gzXWabRSvmt1nrl7sW6cjxljuuQ
|
||||
awIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
```
|
||||
|
||||
* __请求码__
|
||||
|
||||
这是一个Base64编码的字符串,代表的是长度为256字节的数据。这256字节的数据是 __离线激活信息__ 用 __Navicat激活公钥__ 加密的密文。
|
||||
|
||||
* __离线激活请求信息__
|
||||
|
||||
这是一个JSON风格的字符串。它包含了3个Key:`"K"`、`"DI"`和`"P"`,分别代表 __序列号__、__设备识别码__(与你的电脑硬件信息相关)和 __平台__ (其实就是操作系统类型)。
|
||||
|
||||
例如:
|
||||
> {"K": "xxxxxxxxxxxxxxxx", "DI": "yyyyyyyyyyyyy", "P": "WIN8"}
|
||||
|
||||
* __激活码__
|
||||
|
||||
这是一个Base64编码的字符串,代表的是长度为256字节的数据。这256字节的数据是 __离线激活回复信息__ 用 __Navicat激活私钥__ 加密的密文,目前我们不知道官方的 __Navicat激活私钥__。
|
||||
|
||||
* __离线激活回复信息__
|
||||
|
||||
和 __离线激活请求信息__ 一样,它也是一个JSON风格的字符串。但是它包含5个Key,分别为`"K"`、`"N"`、`"O"`、`"T"`和`"DI"`.
|
||||
|
||||
`"K"` 和 `"DI"` 的意义与 __离线激活请求信息__ 中的相同,且Value必须与 __离线激活请求信息__ 中的相同。
|
||||
|
||||
`"N"`、`"O"`、`"T"` 分别代表 __注册名__、__组织__、__授权时间__。__注册名__ 和 __组织__ 的值类型为字符串,__授权时间__ 的值类型可以为字符串或整数(感谢@Wizr在issue #10的报告)。
|
||||
|
||||
`"T"` 可以被省略。
|
||||
|
||||
* __序列号__
|
||||
|
||||
这是一个被分为了4个部分的字符串,其中每个部分都是4个字符长。
|
||||
|
||||
__序列号__ 是通过10个字节的数据来生成的。为了表达方便,我用 __uint8_t data[10]__ 来表示这10个字节。
|
||||
|
||||
1. __data[0]__ 和 __data[1]__ 必须分别为 `0x68` 和 `0x2A`。
|
||||
|
||||
这两个字节时Navicat的标志数。
|
||||
|
||||
2. __data[2]__、__data[3]__ 和 __data[4]__ 可以是任意字节,你想设成什么都行。
|
||||
|
||||
3. __data[5]__ 和 __data[6]__ 与你Navicat的语言有关,值如下:
|
||||
|
||||
| 语言类型 | data[5] | data[6] | 发现者 |
|
||||
|------------|-----------|-----------|-----------------|
|
||||
| English | 0xAC | 0x88 | |
|
||||
| 简体中文 | 0xCE | 0x32 | |
|
||||
| 繁體中文 | 0xAA | 0x99 | |
|
||||
| 日本語 | 0xAD | 0x82 | @dragonflylee |
|
||||
| Polski | 0xBB | 0x55 | @dragonflylee |
|
||||
| Español | 0xAE | 0x10 | @dragonflylee |
|
||||
| Français | 0xFA | 0x20 | @Deltafox79 |
|
||||
| Deutsch | 0xB1 | 0x60 | @dragonflylee |
|
||||
| 한국어 | 0xB5 | 0x60 | @dragonflylee |
|
||||
| Русский | 0xEE | 0x16 | @dragonflylee |
|
||||
| Português | 0xCD | 0x49 | @dragonflylee |
|
||||
|
||||
根据 __Navicat 12 for Mac x64__ 版本残留的符号信息可知这两个字节为 __Product Signature__。
|
||||
|
||||
4. __data[7]__ 是Navicat产品ID。(感谢 @dragonflylee 和 @Deltafox79)这是 __commercial license__ 还是 __non-commercial license__。
|
||||
|
||||
|Product Name |Enterprise|Standard|Educational|Essentials|
|
||||
|---------------------|:--------:|:------:|:---------:|:--------:|
|
||||
|Navicat Report Viewer|0x0B | | | |
|
||||
|Navicat Data Modeler | |0x47 |0x4A | |
|
||||
|Navicat Premium |0x65 | |0x66 |0x67 |
|
||||
|Navicat MySQL |0x68 |0x69 |0x6A |0x6B |
|
||||
|Navicat PostgreSQL |0x6C |0x6D |0x6E |0x6F |
|
||||
|Navicat Oracle |0x70 |0x71 |0x72 |0x73 |
|
||||
|Navicat SQL Server |0x74 |0x75 |0x76 |0x77 |
|
||||
|Navicat SQLite |0x78 |0x79 |0x7A |0x7B |
|
||||
|Navicat MariaDB |0x7C |0x7D |0x7E |0x7F |
|
||||
|Navicat MongoDB |0x80 |0x81 |0x82 | |
|
||||
|
||||
5. __data[8]__ 的高4位代表 __版本号__。低4位未知,但可以用来延长激活期限,可取的值有`0000`和`0001`。
|
||||
|
||||
例如:
|
||||
|
||||
对于 __Navicat 12__: 高4位必须是`1100`,为`12`的二进制形式。
|
||||
对于 __Navicat 11__: 高4位必须是`1011`,为`11`的二进制形式。
|
||||
|
||||
6. __data[9]__ 目前暂未知,但如果你想要 __not-for-resale license__ 的话可以设成`0xFD`、`0xFC`或`0xFB`。
|
||||
|
||||
根据 __Navicat 12 for Mac x64__ 版本残留的符号信息可知:
|
||||
|
||||
* `0xFB`是 __Not-For-Resale-30-days__ license.
|
||||
* `0xFC`是 __Not-For-Resale-90-days__ license.
|
||||
* `0xFD`是 __Not-For-Resale-365-days__ license.
|
||||
* `0xFE`是 __Not-For-Resale__ license.
|
||||
* `0xFF`是 __Site__ license.
|
||||
|
||||
-----------------
|
||||
|
||||
之后Navicat使用 __ECB__ 模式的 __DES__ 算法来加密 __data[10]__ 的后8字节,也就是 __data[2]__ 到 __data[9]__ 的部分。
|
||||
|
||||
相应的DES密钥为:
|
||||
|
||||
```cpp
|
||||
unsigned char DESKey = { 0x64, 0xAD, 0xF3, 0x2F, 0xAE, 0xF2, 0x1A, 0x27 };
|
||||
```
|
||||
|
||||
之后编码 __data[10]__: __(使用Base32编码)__
|
||||
|
||||
1. 将 __data[10]__ 视作为一个80位长的数据。
|
||||
|
||||
如果 __data[10]__ 以`0x68`和`0x2A`开始的话,80位长的数据应该为`01011000 00101010......`
|
||||
|
||||
2. 将80位长的数据分为16个5位长的块。
|
||||
|
||||
如果 __data[10]__ 以`0x68`和`0x2A`开始的话,16个5位长的块应为`01011`、 `00000`、`10101`、`0....`
|
||||
|
||||
3. 这样每一块的值就会小于32。将它们通过下表编码:
|
||||
|
||||
```cpp
|
||||
char EncodeTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
||||
```
|
||||
|
||||
你就会得到一个16字节的字符串。
|
||||
|
||||
如果 __uint8_t data[10]__ 以`0x68`和`0x2A`开始的话,编码之后应该以`"N"`、`"A"`、`"V"`打头。
|
||||
|
||||
4. 将16字节的字符串分成4个4字节的小块,然后用`"-"`连接就可以得到 __序列号__。
|
||||
|
||||
## 3. 激活过程
|
||||
|
||||
1. 检查用户输入的 __序列号__ 是否合法。
|
||||
|
||||
2. 在用户点击了`激活`按钮之后,Navicat会先尝试在线激活。如果失败,用户可以选择离线激活。
|
||||
|
||||
3. Navicat会使用用户输入的 __序列号__ 以及从用户电脑收集来的信息生成 __离线激活请求信息__,然后用 __Navicat激活公钥__ 加密,并将密文用Base64编码,最后得到 __请求码__。
|
||||
|
||||
4. 正常流程下,__请求码__ 应该通过可访问Internet的电脑发送给Navicat的官方激活服务器。之后Navicat的官方激活服务器会返回一个合法的 __激活码__。
|
||||
|
||||
但现在我们使用注册机来扮演官方激活服务器的角色,只是Navicat软件里的激活公钥得换成自己的公钥:
|
||||
|
||||
1. 根据 __请求码__, 获得`"DI"`值和`"K"`值。
|
||||
|
||||
2. 用`"K"`值、用户名、组织名和`"DI"`值填写 __离线激活回复信息__。
|
||||
|
||||
3. 用自己的2048位RSA私钥加密 __离线激活回复信息__,你将会得到256字节的密文。
|
||||
|
||||
4. 用Base64编码这256字节的密文,就可以得到 __激活码__。
|
||||
|
||||
5. 在Navicat软件中填入 __激活码__ 即可完成离线激活。
|
||||
|
||||
## 4. 如何使用这个Keygen
|
||||
1. [从这里](https://github.com/DoubleLabyrinth/navicat-keygen/releases)下载最新的release。
|
||||
|
||||
2. 替换掉`navicat.exe`或`libcc.dll`里的 __Navicat激活公钥__。
|
||||
|
||||
```bash
|
||||
navicat-patcher.exe <Navicat 安装路径> <RSA私钥文件>
|
||||
```
|
||||
|
||||
RSA私钥文件可以为RegPrivateKey.pem
|
||||
|
||||
例如:
|
||||
|
||||
```bash
|
||||
C:\Users\DoubleSine\Github\navicat-keygen\x64\Release>navicat-patcher.exe "C:\Program Files\PremiumSoft\Navicat Premium 12" RegPrivateKey.pem
|
||||
Target has been found: navicat.exe
|
||||
Solution0 has been done successfully.
|
||||
|
||||
Keyword0 has been found: offset = +0x02048200.
|
||||
Keyword1 has been found: offset = +0x006C4E29.
|
||||
Keyword2 has been found: offset = +0x02047F10.
|
||||
Keyword3 has been found: offset = +0x006C4E0F.
|
||||
Keyword4 has been found: offset = +0x02047F04.
|
||||
|
||||
@Offset +0x02048200, write string:
|
||||
"D75125B70767B94145B47C1CB3C0755E7CCB8825C5DCE0C58ACF944E082801409A02472FAFFD1CD77864BB821AE36766FEEDE6A24F12662954168BFA314BD95032B9D82445355ED7784ADAC1C58775D2"
|
||||
|
||||
@Offset +0x006C4E29, write uint32_t:
|
||||
0x0520738A
|
||||
|
||||
@Offset +0x02047F10, write string:
|
||||
"20EEA059669FE4E949F414710A6C11CF68B5318B445D2D0CA85471E9DC382F271E974315F2F3645C2613BF60669584CF0A7531B1E5D2D281097E32A6B17286E8A9BDD06A17A036BC8949C9069CA3A166C251D325A7EAF81DB272CF4E277CC487D6BACB83C1059BBC0D45F49CBB6EA2C0E8033039CA575A939C8FF705FFA1FCA9DD53FD10447EE8D2F48128298E5DAB483F7A1500C455AFE33BB7FB280C39686CC45C7EC8C024EBF1089040D6636FF02E0E2A61092168A5CB105DBF3F5C6EB5C10D7392A46254B6E34DD4365F778ED199A52C6AB931416453CB8A677C90A6674BA5D546B25CDEC9C2E0B067729A6067FB1106B3BF7BBD56B888B5321484779570040B2095CD410D3B33F77BCFC9C24CA5A60003E342F110D35AA4714BFC8B3D9840BB3C8C286C5E353D5DEC4351A27E6E403AED2A21BBD0EA4194FB65B37F301A2E86BF9E9F8BBBFAA2400410ABC7833B3CCAAC66F27F873990E2D97BB36A70A5C9E4E3647C3AD0FAA716820A0BDC15CA8D7392"
|
||||
|
||||
@Offset +0x006C4E0F, write uint32_t:
|
||||
0x00004708
|
||||
|
||||
@Offset +0x02047F04, write string:
|
||||
"64308"
|
||||
|
||||
Solution1 has been done successfully.
|
||||
|
||||
```
|
||||
|
||||
3. 接下来,还是在console中:
|
||||
|
||||
```bash
|
||||
navicat-keygen.exe RegPrivateKey.pem
|
||||
```
|
||||
|
||||
你会被要求选择Navicat产品类别、语言以及输入主版本号。之后会随机生成一个 __序列号__。
|
||||
|
||||
例如:
|
||||
|
||||
```bash
|
||||
C:\Users\DoubleSine\Github\navicat-keygen\x64\Release>navicat-keygen.exe RegPrivateKey.pem
|
||||
Select Navicat product:
|
||||
1. DataModeler
|
||||
2. Premium
|
||||
3. MySQL
|
||||
4. PostgreSQL
|
||||
5. Oracle
|
||||
6. SQLServer
|
||||
7. SQLite
|
||||
8. MariaDB
|
||||
9. MongoDB
|
||||
10. ReportViewer
|
||||
|
||||
(input index)> 1
|
||||
|
||||
Select product language:
|
||||
1. English
|
||||
2. Simplified Chinese
|
||||
3. Traditional Chinese
|
||||
4. Japanese
|
||||
5. Polish
|
||||
6. Spanish
|
||||
7. French
|
||||
8. German
|
||||
9. Korean
|
||||
10. Russian
|
||||
11. Portuguese
|
||||
|
||||
(input index)> 0
|
||||
|
||||
(input major version number)> 12
|
||||
|
||||
Serial number:
|
||||
NAVI-2ORL-MJQC-7WFO
|
||||
|
||||
Your name:
|
||||
```
|
||||
|
||||
你可以使用这个序列号暂时激活Navicat。
|
||||
|
||||
接下来你会被要求输入`用户名`和`组织名`;请随便填写,但不要太长。
|
||||
* `<Navicat installation path>`: Navicat的完整安装路径。
|
||||
|
||||
例如:
|
||||
__这个参数必须指定。__
|
||||
|
||||
```bash
|
||||
Your name: DoubleLabyrinth
|
||||
Your organization: DoubleLabyrinth
|
||||
Input request code (in Base64), input empty line to end:
|
||||
```
|
||||
* `[RSA-2048 PEM file]`: RSA-2048私钥文件的完整路径或相对路径。
|
||||
|
||||
之后你会被要求填入 __请求码__。注意 __不要关闭命令行__.
|
||||
__这个参数是可选的。__ 如果未指定,`navicat-patcher.exe`将会在当前目录生成一个新的RSA-2048私钥文件。
|
||||
|
||||
4. 断开网络并打开 Navicat Premium。找到`注册`窗口,并填入keygen给你的 __序列号__。然后点击`激活`按钮。
|
||||
__例如:(在cmd.exe中)__
|
||||
|
||||
5. 一般来说在线激活肯定会失败,这时候Navicat会询问你是否`手动激活`,直接选吧。
|
||||
```
|
||||
navicat-patcher.exe "C:\Program Files\PremiumSoft\Navicat Premium 12"
|
||||
```
|
||||
|
||||
__Navicat Premium 12.1.12 简体中文版已通过测试__。下面将是一份样例输出。
|
||||
|
||||
6. 在`手动激活`窗口你会得到一个请求码,复制它并把它粘贴到keygen里。最后别忘了连按至少两下回车结束输入。
|
||||
```
|
||||
***************************************************
|
||||
* Navicat Patcher by @DoubleLabyrinth *
|
||||
* Release date: Jan 19 2019 *
|
||||
***************************************************
|
||||
|
||||
例如:
|
||||
Press Enter to continue or Ctrl + C to abort.
|
||||
|
||||
```bash
|
||||
Your name: DoubleLabyrinth
|
||||
Your organization: DoubleLabyrinth
|
||||
Input request code (in Base64), input empty line to end:
|
||||
J517hWX/29aQMITp5UfS/FarX6q8pFKmW1Cl7Nt2UpvmVxhZDn5YBdPw/htDsBbXacNpLtorxfZM
|
||||
Jxv/SZMqHsr7/JqexaaAEfzn5mo6zpatcSRArFoQh2h9IcnjRqziZ8yihkMUesKgsWXvVXMEYk7u
|
||||
D1rc/GhzTf6/2kn0gTKRAlJGsxt+e1p6SOhPuMyzt3AyNvJ2s0o607Nub7vC37FOJF69jN1nOvej
|
||||
uy3bmr2HSPFsh10WqUUYi6F1lzzYIq6nDjQ5CeKrCT2jPfrhoFtRbwJyYDxQOxU/adrm1bg8VjrK
|
||||
XNGeKS67R1nrbBM03IKzPP3pxEGFut4gZdskRw==
|
||||
MESSAGE: PatchSolution0 will be omitted.
|
||||
|
||||
Request Info:
|
||||
{"K":"NAVI2ORLMJQC7WFO", "DI":"Y2eJk9vrvfGudPG7Mbdn", "P":"WIN 8"}
|
||||
MESSAGE: PatchSolution3: Keywords[0] has been found:
|
||||
Relative Machine Code Offset = +0x0000000001644a08
|
||||
Relative Machine Code RVA = +0x0000000001645608
|
||||
Patch Offset = +0x00000000023d56e4
|
||||
Patch Size = 3 byte(s)
|
||||
...
|
||||
...
|
||||
...
|
||||
MESSAGE: PatchSolution3: Keywords[110] has been found:
|
||||
Relative Machine Code Offset = +0x000000000165155e
|
||||
Relative Machine Code RVA = +0x000000000165215e
|
||||
Patch Offset = +0x0000000001651561
|
||||
Patch Size = 1 byte(s)
|
||||
|
||||
Response Info:
|
||||
{"K":"NAVI2ORLMJQC7WFO","DI":"Y2eJk9vrvfGudPG7Mbdn","N":"DoubleLabyrinth","O":"DoubleLabyrinth","T":1534251096}
|
||||
MESSAGE: PatchSolution2 will be omitted.
|
||||
|
||||
License:
|
||||
iFvqOkwsVq/Wutw/hELC5dyweDahl2v8R3bMWcNXS/V49CjpaDEJIHtRLddu/ldg
|
||||
WVGdwdh3aHVJ5k8I6RkUicDvZJH2vLn3o5O9Q/A5ThED0AoYnwu0DLa1gEUlRO68
|
||||
4+uXwo1nZ+xtjLOSxrVh+fLkcvKtd5RDgHS5957qUwjoYBiuePGomtt9mF4NtfaF
|
||||
E7pnfP/OGp8xtWdUfGZ1fESWttKcVXcmOpyF4uTWtluUhFHRk+ZueST/ETyaSx33
|
||||
Kv/zSLBbK8KaVqS2sh5WBs8xVaYxDV08EC8uCCp1euTFOPG5nlrcf7iyILsh6I67
|
||||
xfGRliXvM67jvsxqD200fg==
|
||||
MESSAGE: PatchSolution1: Keywords[0] has been found: offset = +0x021f7390.
|
||||
MESSAGE: PatchSolution1: Keywords[1] has been found: offset = +0x0074bd39.
|
||||
MESSAGE: PatchSolution1: Keywords[2] has been found: offset = +0x021f70a0.
|
||||
MESSAGE: PatchSolution1: Keywords[3] has been found: offset = +0x0074bd1f.
|
||||
MESSAGE: PatchSolution1: Keywords[4] has been found: offset = +0x021f708c.
|
||||
|
||||
```
|
||||
MESSAGE: Generating new RSA private key, it may take a long time.
|
||||
MESSAGE: New RSA private key has been saved to RegPrivateKey.pem.
|
||||
|
||||
Your RSA public key:
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsWnV5hQxlXvDA3Ad4k5N
|
||||
ZLz4cO+iGEPegSovIDcwTo097I+0pXYKPTVl+0iKC5JtJRObb4Xx9yK9gGwqkcxo
|
||||
o6WzKq0xY1jz7X6obxwlQCNse3Os1wr0rIY0UzP1dCpkW/5MwGbFxiB6PEVqkzmJ
|
||||
CmHBzZDRu/jAuL1nyoiGnUStqwENNYhyl4k7r8AiJkBZGMOCrj6v0JfgNna25Ce6
|
||||
QCFojlY4dkYQ5/7njQ3qpLwMeLEXEysMW3aUScSB68/vsHnB4C0fIkwfEPYZ/AC5
|
||||
AqbWHVbNmveB3rjV+tZZxXcLE8ArgKh1Gs+2VtnL09gwHm6WcpyPZ42G6tMDjWyw
|
||||
1wIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
|
||||
******************************************
|
||||
* PatchSulution3 *
|
||||
******************************************
|
||||
@ +023d56e4: 4D 49 49 ---> 4D 49 49
|
||||
@ +01644a63: 42 49 ---> 42 49
|
||||
@ +01644a68: 6A ---> 6A
|
||||
@ +01644ace: 41 ---> 41
|
||||
...
|
||||
...
|
||||
...
|
||||
@ +023d58d4: 36 63 6A ---> 47 36 74
|
||||
@ +023d58d8: 78 6C 6A 75 75 51 61 ---> 4D 44 6A 57 79 77 31
|
||||
@ +023d58e8: 77 49 44 41 ---> 77 49 44 41
|
||||
@ +0165155c: 51 41 ---> 51 41
|
||||
@ +01651561: 42 ---> 42
|
||||
|
||||
******************************************
|
||||
* PatchSulution1 *
|
||||
******************************************
|
||||
@ +0x021f7390
|
||||
Previous:
|
||||
+0x00000000021F7390 44 37 35 31 32 35 42 37 30 37 36 37 42 39 34 31 D75125B70767B941
|
||||
+0x00000000021F73A0 34 35 42 34 37 43 31 43 42 33 43 30 37 35 35 45 45B47C1CB3C0755E
|
||||
+0x00000000021F73B0 37 43 43 42 38 38 32 35 43 35 44 43 45 30 43 35 7CCB8825C5DCE0C5
|
||||
...
|
||||
...
|
||||
...
|
||||
|
||||
@ +0x021f708c
|
||||
Previous:
|
||||
+0x00000000021F7080 31 32 32 35 4f 45 29 2e 00 00 00 00 39 32 39 33 1225OE).....9293
|
||||
+0x00000000021F7090 33 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3...............
|
||||
After:
|
||||
+0x00000000021F7080 31 32 32 35 4f 45 29 2e 00 00 00 00 32 37 45 38 1225OE).....27E8
|
||||
+0x00000000021F7090 45 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 E...............
|
||||
|
||||
MESSAGE: Patch has been done successfully.
|
||||
```
|
||||
|
||||
3. 接下来使用`navicat-keygen.exe`来生成序列号和激活码
|
||||
|
||||
```
|
||||
navicat-keygen.exe <-bin|-text> [-adv] <RSA-2048 PrivateKey(PEM file)>
|
||||
```
|
||||
|
||||
* `<-bin|-text>`: 必须是`-bin`或`-text`。
|
||||
|
||||
如果指定了`-bin`,`navicat-keygen.exe`最终将生成`license_file`文件。这个选项是给Navicat旧激活方式使用的。
|
||||
|
||||
如果指定了`-text`,`navicat-keygen.exe`最终将生成Base64样式的激活码。这个选项是给Navicat新激活方式使用的。
|
||||
|
||||
__这个参数必须指定。__
|
||||
|
||||
* `[-adv]`: 开启高级模式。
|
||||
|
||||
__这个参数是可选的。__ 如果指定了这个参数,`navicat-keygen.exe`将会要求你手工填写产品ID号、语言标识号。这个选项一般是给以后用的。
|
||||
|
||||
* `<RSA-2048 PrivateKey(PEM file)>`: RSA-2048私钥文件的完整路径或相对路径。
|
||||
|
||||
__这个参数必须指定。__
|
||||
|
||||
__例如:(在cmd.exe中)__
|
||||
|
||||
```bash
|
||||
navicat-keygen.exe -text .\RegPrivateKey.pem
|
||||
```
|
||||
|
||||
你会被要求选择Navicat产品类别、语言以及输入主版本号。之后会随机生成一个序列号。
|
||||
|
||||
```
|
||||
Select Navicat product:
|
||||
0. DataModeler
|
||||
1. Premium
|
||||
2. MySQL
|
||||
3. PostgreSQL
|
||||
4. Oracle
|
||||
5. SQLServer
|
||||
6. SQLite
|
||||
7. MariaDB
|
||||
8. MongoDB
|
||||
9. ReportViewer
|
||||
|
||||
(Input index)> 1
|
||||
|
||||
Select product language:
|
||||
0. English
|
||||
1. Simplified Chinese
|
||||
2. Traditional Chinese
|
||||
3. Japanese
|
||||
4. Polish
|
||||
5. Spanish
|
||||
6. French
|
||||
7. German
|
||||
8. Korean
|
||||
9. Russian
|
||||
10. Portuguese
|
||||
|
||||
(Input index)> 1
|
||||
|
||||
(Input major version number, range: 0 ~ 15, default: 12)> 12
|
||||
|
||||
Serial number:
|
||||
NAVO-2ORP-IN5A-GQEE
|
||||
|
||||
Your name:
|
||||
```
|
||||
|
||||
你可以使用这个序列号暂时激活Navicat。
|
||||
|
||||
接下来你会被要求输入`用户名`和`组织名`;请随便填写,但不要太长。
|
||||
|
||||
```
|
||||
Your name: DoubleLabyrinth
|
||||
Your organization: DoubleLabyrinth
|
||||
Input request code (in Base64), input empty line to end:
|
||||
```
|
||||
|
||||
之后你会被要求填入请求码。注意 __不要关闭命令行__.
|
||||
|
||||
4. __断开网络__ 并打开Navicat。找到`注册`窗口,并填入keygen给你的序列号。然后点击`激活`按钮。
|
||||
|
||||
5. 一般来说在线激活肯定会失败,这时候Navicat会询问你是否`手动激活`,直接选吧。
|
||||
|
||||
6. 在`手动激活`窗口你会得到一个请求码,复制它并把它粘贴到keygen里。最后别忘了连按至少两下回车结束输入。
|
||||
|
||||
```bash
|
||||
Your name: DoubleLabyrinth
|
||||
Your organization: DoubleLabyrinth
|
||||
|
||||
Input request code (in Base64), input empty line to end:
|
||||
t2U+0yfE2FfnbjyhCXa0lglZOHu9Ntc3qyGiPbR6xb1QoU63/9BVfdaCq0blwVycXPyT/Vqw5joIKdM5oCRR/afCPM7iRcyhQMAnvqwc+AOKCqayVV+SqKLvtR/AbREI12w++PQ6Ewfs4A8PgB8OJ9G0jKt6Q/iJRblqi2WWw9mwy+YHcYYh3UAfygTnyj/xl+MzRymbY0lkus+6LPtpDecVsFFhM7F32Ee1QPwISko7bAkHOtkt+joPfYDdn9PDGZ4HEmeLvH6UqZCXkzgaAfynB7cQZFEkId8FsW2NGkbpM7wB2Hi3fNFgOIjutTprixTdbpFKn4w6gGc28ve23A==
|
||||
|
||||
Request Info:
|
||||
{"K":"NAVO2ORPIN5AGQEE", "DI":"R91j6WyMhxHznAKSxxxx", "P":"WIN"}
|
||||
|
||||
Response Info:
|
||||
{"K":"NAVO2ORPIN5AGQEE","DI":"R91j6WyMhxHznAKSxxxx","N":"DoubleLabyrinth","O":"DoubleLabyrinth","T":1547826060}
|
||||
|
||||
License:
|
||||
lRF18o+ZhBphyN0U5kFLHtAAGGXuvhqOcxNuvAk4dJcGeR0ISuw74mQvAfdNjv0T
|
||||
I5NZFzqIJvrzM0XeR88q+3kmZkECuxwwWHP3zzDPhPiylcTV4DoGZ1tfoViUSYQc
|
||||
LgXG0Fl7koZeP61YOKQ8GfX+Xk2ZTM64bYaF7NlhonM+GQUJCCF2JThmrP921t2p
|
||||
b/E5pV6fLOYMM13881ZQcQcltMNVDZn4lzgzKRFFxCQFaTl6fJMHZdYVmICQTHtI
|
||||
sNaym0zduc8/cv34mgJ+7NseXmsEPCdjrZ59wgfPsLhZLXqtfxi5hGWw4NMa3Sb2
|
||||
UI8dzqFzRp/hSDEM0mEqiA==
|
||||
```
|
||||
|
||||
4. 如果不出意外,你会得到一个看似用Base64编码的激活码。直接复制它,并把它粘贴到Navicat的`手动激活`窗口,最后点`激活`按钮。如果没什么意外的话应该能成功激活。
|
||||
|
||||
7. 如果不出意外,你会得到一个看似用Base64编码的 __激活码__。直接复制它,并把它粘贴到Navicat的`手动激活`窗口,最后点`激活`按钮。如果没什么意外的话应该能成功激活。
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
This file credits all the contributors of the Capstone engine project.
|
||||
|
||||
Key developers
|
||||
==============
|
||||
1. Nguyen Anh Quynh <aquynh -at- gmail.com>
|
||||
- Core engine
|
||||
- Bindings: Python, Ruby, OCaml, Java, C#
|
||||
|
||||
2. Tan Sheng Di <shengdi -at- coseinc.com>
|
||||
- Bindings: Ruby
|
||||
|
||||
3. Ben Nagy <ben -at- coseinc.com>
|
||||
- Bindings: Ruby, Go
|
||||
|
||||
4. Dang Hoang Vu <dang.hvu -at- gmail.com>
|
||||
- Bindings: Java
|
||||
|
||||
|
||||
Beta testers (in random order)
|
||||
==============================
|
||||
Pancake
|
||||
Van Hauser
|
||||
FX of Phenoelit
|
||||
The Grugq, The Grugq <-- our hero for submitting the first ever patch!
|
||||
Isaac Dawson, Veracode Inc
|
||||
Patroklos Argyroudis, Census Inc. (http://census-labs.com)
|
||||
Attila Suszter
|
||||
Le Dinh Long
|
||||
Nicolas Ruff
|
||||
Gunther
|
||||
Alex Ionescu, Winsider Seminars & Solutions Inc.
|
||||
Snare
|
||||
Daniel Godas-Lopez
|
||||
Joshua J. Drake
|
||||
Edgar Barbosa
|
||||
Ralf-Philipp Weinmann
|
||||
Hugo Fortier
|
||||
Joxean Koret
|
||||
Bruce Dang
|
||||
Andrew Dunham
|
||||
|
||||
|
||||
Contributors (in no particular order)
|
||||
=====================================
|
||||
(Please let us know if you want to have your name here)
|
||||
|
||||
Ole André Vadla Ravnås (author of the 100th Pull-Request in our Github repo, thanks!)
|
||||
Axel "0vercl0k" Souchet (@0vercl0k) & Alex Ionescu: port to MSVC.
|
||||
Daniel Pistelli: Cmake support.
|
||||
Peter Hlavaty: integrate Capstone for Windows kernel drivers.
|
||||
Guillaume Jeanne: Ocaml binding.
|
||||
Martin Tofall, Obsidium Software: Optimize X86 performance & size + x86 encoding features.
|
||||
David Martínez Moreno & Hilko Bengen: Debian package.
|
||||
Félix Cloutier: Xcode project.
|
||||
Benoit Lecocq: OpenBSD package.
|
||||
Christophe Avoinne (Hlide): Improve memory management for better performance.
|
||||
Michael Cohen & Nguyen Tan Cong: Python module installer.
|
||||
Adel Gadllah, Francisco Alonso & Stefan Cornelius: RPM package.
|
||||
Felix Gröbert (Google): fuzz testing harness.
|
||||
Xipiter LLC: Capstone logo redesigned.
|
||||
Satoshi Tanda: Support Windows kernel driver.
|
||||
Tang Yuhang: cstool.
|
||||
Andrew Dutcher: better Python setup.
|
||||
Ruben Boonen: PowerShell binding.
|
||||
David Zimmer: VB6 binding.
|
||||
Philippe Antoine: Integration with oss-fuzz and various fixes.
|
||||
Bui Dinh Cuong: Explicit registers accessed for Arm64.
|
||||
Vincent Bénony: Explicit registers accessed for X86.
|
||||
Adel Gadllah, Francisco Alonso & Stefan Cornelius: RPM package.
|
||||
Felix Gröbert (Google): fuzz testing harness.
|
||||
Daniel Collin & Nicolas Planel: M68K architecture.
|
||||
Pranith Kumar: Explicit registers accessed for Arm64.
|
||||
Xipiter LLC: Capstone logo redesigned.
|
||||
Satoshi Tanda: Support Windows kernel driver.
|
||||
Koutheir Attouchi: Support for Windows CE.
|
||||
Fotis Loukos: TMS320C64x architecture.
|
||||
Wolfgang Schwotzer: M680X architecture.
|
||||
Philippe Antoine: Integration with oss-fuzz and various fixes.
|
||||
Stephen Eckels (stevemk14ebr): x86 encoding features
|
||||
@@ -0,0 +1,701 @@
|
||||
This file details the changelog of Capstone.
|
||||
|
||||
---------------------------------
|
||||
Version 4.0.1: January 10th, 2019
|
||||
|
||||
|
||||
[ Core ]
|
||||
|
||||
- Fix some issues for packaging (Debian, Gentoo).
|
||||
- Better support for building with Mingw.
|
||||
- cstool has new option -s to turn on skipdata mode.
|
||||
- cstool -v now report build settings of the core.
|
||||
- Add suite/capstone_get_setup.c so users can integrate with their own code
|
||||
to retrieve Capstone settings at build time.
|
||||
|
||||
|
||||
[ Arm ]
|
||||
|
||||
- Fix 4.0 regression: the `tbh [r0, r1, lsl #1]` instruction sets the operand.shift.value back again (see #1317)
|
||||
- Remove ARM_REG_PC group for BX instruction.
|
||||
|
||||
|
||||
[ X86 ]
|
||||
|
||||
- Fix: endbr32 and endbr64 instructions are now properly decoded in both CS_MODE_32 and CS_MODE_64 (#1129)
|
||||
|
||||
|
||||
[ M680X ]
|
||||
|
||||
- Fix some issues reported by clang-analyzer (#1329).
|
||||
|
||||
|
||||
[ Python ]
|
||||
|
||||
- Fix skipdata setup.
|
||||
- Add getter/setter for skipdata_mnem, skipdata_callback.
|
||||
|
||||
|
||||
---------------------------------
|
||||
Version 4.0: December 18th, 2018
|
||||
|
||||
|
||||
[ Core ]
|
||||
|
||||
- New APIs: cs_regs_access()
|
||||
- Add new options for cs_option(): CS_OPT_MNEMONIC & CS_OPT_UNSIGNED & CS_OPT_SYNTAX_MASM.
|
||||
- Various updates & bugfixes for all architectures.
|
||||
- Add 4 new architectures: EVM, M68K, M680X & TMS320C64x.
|
||||
- Add new group types: CS_GRP_PRIVILEGE & CS_GRP_BRANCH_RELATIVE.
|
||||
- Add new error types: CS_ERR_X86_MASM.
|
||||
|
||||
|
||||
[ X86 ]
|
||||
|
||||
- Add XOP code condition type in x86_xop_cc.
|
||||
- Add some info on encoding to cs_x86 in cs_x86_encoding.
|
||||
- Add register flags update in cs_x86.{eflags, fpu_flags}
|
||||
- Change cs_x86.disp type from int32_t to int64_t.
|
||||
- Add new groups: X86_GRP_VM & X86_GRP_FPU.
|
||||
- Lots of new instructions (AVX)
|
||||
|
||||
|
||||
[ ARM64 ]
|
||||
|
||||
- Add instruction ARM64_INS_NEGS & ARM64_INS_NGCS.
|
||||
|
||||
|
||||
[ Mips ]
|
||||
|
||||
- Add mode CS_MODE_MIPS2.
|
||||
|
||||
|
||||
[ PPC ]
|
||||
|
||||
- Change cs_ppc_op.imm type from int32_t to int64_t.
|
||||
- Add new groups: PPC_GRP_ICBT, PPC_GRP_P8ALTIVEC, PPC_GRP_P8VECTOR & PPC_GRP_QPX.
|
||||
- Lots of new instructions (QPX among them)
|
||||
|
||||
|
||||
[ Sparc ]
|
||||
|
||||
- Change cs_sparc_op.imm type from int32_t to int64_t.
|
||||
|
||||
|
||||
[ Binding ]
|
||||
|
||||
- New bindings: PowerShell & VB6
|
||||
|
||||
|
||||
---------------------------------
|
||||
Version 3.0.5: July 18th, 2018
|
||||
|
||||
|
||||
[ Core ]
|
||||
|
||||
- Fix the include path for Android builds when building cstool.
|
||||
- Add posibility to disable universal build for Mac OS.
|
||||
- cstool: Separate instruction bytes by spaces.
|
||||
- Fix code path of pkg-config in Cmake.
|
||||
- Update XCode project for XCode 9.1.
|
||||
- Add Cortex-M support to cstool.
|
||||
- Cmake forces to be build using MT with MSVC.
|
||||
- Better support for Mac OS kernel.
|
||||
|
||||
|
||||
[ X86 ]
|
||||
|
||||
- Fix some issues in handling EVEX & VEX3 instructions.
|
||||
- Fix immediate operand for AND instruction in ATT mode.
|
||||
- Fix ATT syntax when imm operand is 0.
|
||||
- Better handle XACQUIRE/XRELEASE.
|
||||
- Fix imm operand of RETF.
|
||||
|
||||
|
||||
[ ARM ]
|
||||
|
||||
- Fix an integer overlow bug.
|
||||
|
||||
|
||||
[ ARM64 ]
|
||||
|
||||
- Bug fix for incorrect operand type in certain load/store instructions.
|
||||
|
||||
|
||||
[ Mips ]
|
||||
|
||||
- Mode CS_MODE_MIPS32R6 automatically sets CS_MODE_32
|
||||
|
||||
|
||||
[ PPC ]
|
||||
|
||||
- Fix endian check.
|
||||
|
||||
|
||||
[ Sparc ]
|
||||
|
||||
- Fix an integer overlow bug.
|
||||
|
||||
|
||||
[ SystemZ ]
|
||||
|
||||
- Fix an integer overlow bug.
|
||||
|
||||
|
||||
[ Python binding ]
|
||||
|
||||
- Raise error on accessing irrelevant data fields if skipdata & detail modes are enable.
|
||||
|
||||
|
||||
---------------------------------
|
||||
Version 3.0.5-rc3: July 31st, 2017
|
||||
|
||||
|
||||
[ Core ]
|
||||
|
||||
- Fix compilation for MacOS kernel extension
|
||||
- cstool to support armbe and arm64be modes
|
||||
- Add nmake.bat for Windows build
|
||||
- Fix an integer overflow for Windows kernel driver
|
||||
- Support to embedded Capstone into MacOS kernel
|
||||
- cstool: fix mips64 mode
|
||||
- Fix a compiling error in MS Visual Studio 2015
|
||||
- Install pkgconfig file with CMake build
|
||||
- Fix SOVERSION property of CMake build
|
||||
- Properly handle switching to Endian mode at run-time for Arm, Arm64, Mips & Sparc
|
||||
- Fix MingW build
|
||||
- Better handle CMake installation for Linux 64bit
|
||||
|
||||
|
||||
[ X86 ]
|
||||
|
||||
- Support BND prefix of Intel MPX extension
|
||||
- Correct operand size for CALL/JMP in 64bit mode with prefix 0x66
|
||||
- LOCK NOP is a valid instruction
|
||||
- Fix ATT syntax for instruction with zero offset segment register
|
||||
- LES/LDS are invalid in 64bit mode
|
||||
- Fix number of operands for some MOV instructions
|
||||
|
||||
|
||||
[ ARM ]
|
||||
|
||||
- Fix POP reg to update SP register
|
||||
- Update flags for UADD8 instruction
|
||||
|
||||
|
||||
[ ARM64 ]
|
||||
|
||||
- Better performance with new lookup table
|
||||
- Handle system registers added in ARMv8.1/2
|
||||
|
||||
|
||||
[ Java binding ]
|
||||
|
||||
- Better handle input with invalid code
|
||||
|
||||
|
||||
[ Visual Basic binding ]
|
||||
|
||||
- New binding
|
||||
|
||||
---------------------------------
|
||||
Version 3.0.5-rc2: March 2nd, 2017
|
||||
|
||||
|
||||
[ Core ]
|
||||
|
||||
- Fix build for Visual Studio 2012
|
||||
- Fix X86_REL_ADDR macro
|
||||
- Add CS_VERSION_MAJOR, CS_VERSION_MINOR, CS_VERSION_EXTRA
|
||||
- Better support for embedding Capstone into Windows kernel drivers
|
||||
- Support to embedded Capstone into MacOS kernel
|
||||
- Support MacOS 10.11 and up
|
||||
- Better support for Cygwin
|
||||
- Support build packages for FreeBSD & DragonflyBSD
|
||||
- Add a command-line tool "cstool"
|
||||
- Properly handle switching to Endian mode at run-time for Arm, Arm64, Mips & Sparc
|
||||
|
||||
|
||||
[ X86 ]
|
||||
|
||||
- Some random 16-bit code can be handled wrongly.
|
||||
- Remove abundant operand type X86_OP_FP
|
||||
- Fix instructions MOVQ, LOOP, LOOPE, LOOPNE, CALL/JMP rel16, REPNE LODSD, MOV *AX, MOFFS, FAR JMP/CALL
|
||||
- Add X86_REG_EFLAGS for STC and STD
|
||||
- Fix instruction attributes for SYSEXIT, MOVW, ROL, LGS, SLDT
|
||||
- Rename registers ST0-ST7 to be consistent with asm output
|
||||
|
||||
|
||||
[ ARM ]
|
||||
|
||||
- Properly handle IT instruction
|
||||
- Fix LDRSB
|
||||
- Fix writeback for LDR
|
||||
- Fix Thumb BigEndian setup
|
||||
|
||||
|
||||
[ ARM64 ]
|
||||
|
||||
- Fix arith extender
|
||||
- Fix writeback for LDR
|
||||
- Rename enum arm64_mrs_reg to arm64_sysreg
|
||||
|
||||
|
||||
[ PowerPC ]
|
||||
|
||||
- Print 0 offset for memory operand
|
||||
|
||||
|
||||
[ Sparc ]
|
||||
|
||||
- Fix POPC instruction
|
||||
|
||||
|
||||
[ Python binding ]
|
||||
|
||||
- Better PyPy support
|
||||
- Add __version__
|
||||
- Better support for Python 3
|
||||
- Fix CS_SKIPDATA_CALLBACK prototype
|
||||
- Cast skipdata function inside binding to simplify the API
|
||||
|
||||
|
||||
[ Java binding ]
|
||||
|
||||
- Better handle input with invalid code
|
||||
|
||||
|
||||
[ PowerShell ]
|
||||
|
||||
- New binding
|
||||
|
||||
---------------------------------
|
||||
Version 3.0.4: July 15th, 2015
|
||||
|
||||
|
||||
[ Library ]
|
||||
|
||||
- Improve cross-compile for Android using Android NDK.
|
||||
- Support cross-compile for AArch64 Android (with Linux GCC).
|
||||
- Removed osxkernel_inttypes.h that is incompatible with BSD license.
|
||||
- Make it possible to compile with CC having a space inside (like "ccache gcc").
|
||||
|
||||
|
||||
[ X86 ]
|
||||
|
||||
- Fix a null pointer dereference bug on handling code with special prefixes.
|
||||
- Properly handle AL/AX/EAX operand for OUT instruction in AT&T syntax.
|
||||
- Print immediate operand in positive form in some algorithm instructions.
|
||||
- Properly decode some SSE instructions.
|
||||
|
||||
|
||||
[ PowerPC ]
|
||||
|
||||
- Fixed a memory corruption bug.
|
||||
- Fixed a memory corruption bug for the engine built in DIET mode.
|
||||
|
||||
|
||||
[ Mips ]
|
||||
|
||||
- Fixed instruction ID of SUBU instruction.
|
||||
- Fixed a memory corruption bug.
|
||||
|
||||
|
||||
[ Arm ]
|
||||
|
||||
- Fixed a memory corruption bug on IT instruction.
|
||||
|
||||
|
||||
[ XCore ]
|
||||
|
||||
- Fixed a memory corruption bug when instruction has a memory operand.
|
||||
|
||||
|
||||
[ Python ]
|
||||
|
||||
- Support Virtualenv.
|
||||
- setup.py supports option --user if not in a virtualenv to allow for local usage.
|
||||
- Properly handle the destruction of Cs object in the case the shared library
|
||||
was already unloaded.
|
||||
|
||||
---------------------------------
|
||||
Version 3.0.3: May 08th, 2015
|
||||
|
||||
|
||||
[ Library ]
|
||||
|
||||
- Support to embed into Mac OS X kernel extensions.
|
||||
- Now it is possible to compile Capstone with older C compilers, such as
|
||||
GCC 4.8 on Ubuntu 12.04.
|
||||
- Add "test_iter" to MSVC project.
|
||||
|
||||
|
||||
[ X86 ]
|
||||
|
||||
- All shifted instructions SHL, SHR, SAL, SAR, RCL, RCR, ROL & ROR now support
|
||||
$1 as first operand in *AT&T* syntax (so we have "rcll $1, %edx" instead of
|
||||
"rcll %edx").
|
||||
- CMPXCHG16B is a valid instruction with LOCK prefix.
|
||||
- Fixed a segfault on the input of 0xF3.
|
||||
|
||||
|
||||
[ Arm ]
|
||||
|
||||
- BLX instruction modifies PC & LR registers.
|
||||
|
||||
|
||||
[ Sparc ]
|
||||
|
||||
- Improved displacement decoding for sparc banching instructions.
|
||||
|
||||
|
||||
[ Python binding ]
|
||||
|
||||
- Fix for Cython so it can properly initialize.
|
||||
- X86Op.avx_zero_mask now has c_bool type, but not c_uint8 type.
|
||||
- Properly support compile with Cygwin & install binding (setup.py).
|
||||
|
||||
---------------------------------
|
||||
Version 3.0.2: March 11th, 2015
|
||||
|
||||
|
||||
[ Library ]
|
||||
|
||||
- On *nix, only export symbols that are part of the API (instead of all
|
||||
the internal symbols).
|
||||
|
||||
|
||||
[ X86 ]
|
||||
|
||||
- Do not consider 0xF2 as REPNE prefix if it is a part of instruction encoding.
|
||||
- Fix implicit registers read/written & instruction groups of some instructions.
|
||||
- More flexible on the order of prefixes, so better handle some tricky
|
||||
instructions.
|
||||
- REPNE prefix can go with STOS & MOVS instructions.
|
||||
- Fix a compilation bug for X86_REDUCE mode.
|
||||
- Fix operand size of instructions with operand PTR []
|
||||
|
||||
|
||||
[ Arm ]
|
||||
|
||||
- Fix a bug where arm_op_mem.disp is wrongly calculated (in DETAIL mode).
|
||||
- Fix a bug on handling the If-Then block.
|
||||
|
||||
|
||||
[ Mips ]
|
||||
|
||||
- Sanity check for the input size for MIPS64 mode.
|
||||
|
||||
|
||||
[ MSVC ]
|
||||
|
||||
- Compile capstone.dll with static runtime MSVCR built in.
|
||||
|
||||
|
||||
[ Python binding ]
|
||||
|
||||
- Fix a compiling issue of Cython binding with gcc 4.9.
|
||||
|
||||
---------------------------------
|
||||
Version 3.0.1: February 03rd, 2015
|
||||
|
||||
[ X86 ]
|
||||
|
||||
- Properly handle LOCK, REP, REPE & REPNE prefixes.
|
||||
- Handle undocumented immediates for SSE's (V)CMPPS/PD/SS/SD instructions.
|
||||
- Print LJUMP/LCALL without * as prefix for Intel syntax.
|
||||
- Handle REX prefix properly for segment/MMX related instructions (x86_64).
|
||||
- Instruction with length > 15 is consider invalid.
|
||||
- Handle some tricky encodings for instructions MOVSXD, FXCH, FCOM, FCOMP,
|
||||
FSTP, FSTPNCE, NOP.
|
||||
- Handle some tricky code for some X86_64 instructions with REX prefix.
|
||||
- Add missing operands in detail mode for PUSH , POP , IN/OUT reg, reg
|
||||
- MOV32ms & MOV32sm should reference word rather than dword.
|
||||
|
||||
|
||||
[ Arm64 ]
|
||||
|
||||
- BL & BLR instructions do not read SP register.
|
||||
- Print absolute (rather than relative) address for instructions B, BL,
|
||||
CBNZ, ADR.
|
||||
|
||||
|
||||
[ Arm ]
|
||||
|
||||
- Instructions ADC & SBC do not update flags.
|
||||
- BL & BLX do not read SP, but PC register.
|
||||
- Alias LDR instruction with operands [sp], 4 to POP.
|
||||
- Print immediate operand of MVN instruction in positive hexadecimal form.
|
||||
|
||||
|
||||
[ PowerPC ]
|
||||
|
||||
- Fix some compilation bugs when DIET mode is enable.
|
||||
- Populate SLWI/SRWI instruction details with SH operand.
|
||||
|
||||
|
||||
[ Python binding ]
|
||||
|
||||
- Fix a Cython bug when CsInsn.bytes returns a shorten array of bytes.
|
||||
- Fixed a memory leak for Cython disasm functions when we immaturely quit
|
||||
the enumeration of disassembled instructions.
|
||||
- Fix a NULL memory access issue when SKIPDATA & Detail modes are enable
|
||||
at the same time.
|
||||
- Fix a memory leaking bug when when we stop enumeration over the disassembled
|
||||
instructions prematurely.
|
||||
- Export generic operand types & groups (CS_OP_xxx & CS_GRP_xxx).
|
||||
|
||||
---------------------------------
|
||||
Version 3.0: November 19th, 2014
|
||||
|
||||
[ API ]
|
||||
|
||||
- New API: cs_disasm_iter & cs_malloc. See docs/README for tutorials.
|
||||
- Renamed cs_disasm_ex to cs_disasm (cs_disasm_ex is still supported, but
|
||||
marked obsolete to be removed in future)
|
||||
- Support SKIPDATA mode, so Capstone can jump over unknown data and keep going
|
||||
from the next legitimate instruction. See docs/README for tutorials.
|
||||
- More details provided in cs_detail struct for all architectures.
|
||||
- API version was bumped to 3.0.
|
||||
|
||||
|
||||
[ Bindings ]
|
||||
|
||||
- Python binding supports Python3 (besides Python2).
|
||||
- Support Ocaml binding.
|
||||
- Java: add close() method to be used to deinitialize a Capstone object when
|
||||
no longer use it.
|
||||
|
||||
|
||||
[ Architectures ]
|
||||
|
||||
- New architectures: Sparc, SystemZ & XCore.
|
||||
- Important bugfixes for Arm, Arm64, Mips, PowerPC & X86.
|
||||
- Support more instructions for Arm, Arm64, Mips, PowerPC & X86.
|
||||
- Always expose absolute addresses rather than relative addresses (Arm, Arm64,
|
||||
Mips, PPC, Sparc, X86).
|
||||
- Use common instruction operand types REG, IMM, MEM & FP across all
|
||||
architectures (to enable cross-architecture analysis).
|
||||
- Use common instruction group types across all architectures (to enable
|
||||
cross-architecture analysis).
|
||||
|
||||
|
||||
[ X86 ]
|
||||
|
||||
- X86 engine is mature & handles all the malware tricks (that we are aware of).
|
||||
- Added a lot of new instructions (such as AVX512, 3DNow, etc).
|
||||
- Add prefix symbols X86_PREFIX_REP/REPNE/LOCK/CS/DS/SS/FS/GS/ES/OPSIZE/ADDRSIZE.
|
||||
- Print immediate in positive form & hexadecimal for AND/OR/XOR instructions.
|
||||
- More friendly disassembly for JMP16i (in the form segment:offset)
|
||||
|
||||
|
||||
[ Mips ]
|
||||
|
||||
- Engine added supports for new hardware modes: Mips32R6 (CS_MODE_MIPS32R6) &
|
||||
MipsGP64 (CS_MODE_MIPSGP64).
|
||||
- Removed the ABI-only mode CS_MODE_N64.
|
||||
- New modes CS_MODE_MIPS32 & CS_MODE_MIPS64 (to use instead of CS_MODE_32 &
|
||||
CS_MODE_64).
|
||||
|
||||
|
||||
[ ARM ]
|
||||
|
||||
- Support new mode CS_MODE_V8 for Armv8 A32 encodings.
|
||||
- Print immediate in positive form & hexadecimal for AND/ORR/EOR/BIC instructions
|
||||
|
||||
|
||||
[ ARM64 ]
|
||||
|
||||
- Print immediate in hexadecimal for AND/ORR/EOR/TST instructions.
|
||||
|
||||
|
||||
[ PowerPC ]
|
||||
|
||||
- Do not print a dot in front of absolute address.
|
||||
|
||||
|
||||
[ Other features ]
|
||||
|
||||
- Support for Microsoft Visual Studio (so enable Windows native compilation).
|
||||
- Support CMake compilation.
|
||||
- Cross-compile for Android.
|
||||
- Build libraries/tests using XCode project
|
||||
- Much faster, while consuming less memory for all architectures.
|
||||
|
||||
---------------------------------
|
||||
Version 2.1.2: April 3rd, 2014
|
||||
|
||||
This is a stable release to fix some bugs deep in the core. There is no update
|
||||
to any architectures or bindings, so bindings version 2.1 can be used with this
|
||||
version 2.1.2 just fine.
|
||||
|
||||
[ Core changes]
|
||||
|
||||
- Support cross-compilation for all iDevices (iPhone/iPad/iPod).
|
||||
- X86: do not print memory offset in negative form.
|
||||
- Fix a bug in X86 when Capstone cannot handle short instruction.
|
||||
- Print negative number above -9 without prefix 0x (arm64, mips, arm).
|
||||
- Correct the SONAME setup for library versioning (Linux, *BSD, Solaris).
|
||||
- Set library versioning for dylib of OSX.
|
||||
|
||||
---------------------------------
|
||||
Version 2.1.1: March 13th, 2014
|
||||
|
||||
This is a stable release to fix some bugs deep in the core. There is no update
|
||||
to any architectures or bindings, so bindings version 2.1 can be used with this
|
||||
version 2.1.1 just fine.
|
||||
|
||||
[ Core changes]
|
||||
|
||||
- Fix a buffer overflow bug in Thumb mode (ARM). Some special input can
|
||||
trigger this flaw.
|
||||
- Fix a crash issue when embedding Capstone into OSX kernel. This should
|
||||
also enable Capstone to be embedded into other systems with limited stack
|
||||
memory size such as Linux kernel or some firmwares.
|
||||
- Use a proper SONAME for library versioning (Linux).
|
||||
|
||||
---------------------------------
|
||||
Version 2.1: March 5th, 2014
|
||||
|
||||
[ API changes ]
|
||||
|
||||
- API version has been bumped to 2.1.
|
||||
- Change prototype of cs_close() to be able to invalidate closed handle.
|
||||
See http://capstone-engine.org/version_2.1_API.html for more information.
|
||||
- Extend cs_support() to handle more query types, not only about supported
|
||||
architectures. This change is backward compatible, however, so existent code
|
||||
do not need to be modified to support this.
|
||||
- New query type CS_SUPPORT_DIET for cs_support() to ask about diet status of
|
||||
the engine.
|
||||
- New error code CS_ERR_DIET to report errors about newly added diet mode.
|
||||
- New error code CS_ERR_VERSION to report issue of incompatible versions between
|
||||
bindings & core engine.
|
||||
|
||||
|
||||
[ Core changes ]
|
||||
|
||||
- On memory usage, Capstone uses about 40% less memory, while still faster
|
||||
than version 2.0.
|
||||
- All architectures are much smaller: binaries size reduce at least 30%.
|
||||
Especially, X86-only binary reduces from 1.9MB to just 720KB.
|
||||
- Support "diet" mode, in which engine size is further reduced (by around 40%)
|
||||
for embedding purpose. The price to pay is that we have to sacrifice some
|
||||
non-critical data fields. See http://capstone-engine.org/diet.html for more
|
||||
details.
|
||||
|
||||
|
||||
[ Architectures ]
|
||||
|
||||
- Update all 5 architectures to fix bugs.
|
||||
- PowerPC:
|
||||
- New instructions: FMR & MSYNC.
|
||||
- Mips:
|
||||
- New instruction: DLSA
|
||||
- X86:
|
||||
- Properly handle AVX-512 instructions.
|
||||
- New instructions: PSETPM, SALC, INT1, GETSEC.
|
||||
- Fix some memory leaking issues in case of prefixed instructions such
|
||||
as LOCK, REP, REPNE.
|
||||
|
||||
|
||||
[ Python binding ]
|
||||
|
||||
- Verify the core version at initialization time. Refuse to run if its version
|
||||
is different from the core's version.
|
||||
- New API disasm_lite() added to Cs class. This light API only returns tuples of
|
||||
(address, size, mnemonic, op_str), rather than list of CsInsn objects. This
|
||||
improves performance by around 30% in some benchmarks.
|
||||
- New API version_bind() returns binding's version, which might differ from
|
||||
the core's API version if the binding is out-of-date.
|
||||
- New API debug() returns information on Cython support, diet status & archs
|
||||
compiled in.
|
||||
- Fixed some memory leaking bugs for Cython binding.
|
||||
- Fix a bug crashing Cython code when accessing @regs_read/regs_write/groups.
|
||||
- Support diet mode.
|
||||
|
||||
|
||||
[ Java binding ]
|
||||
|
||||
- Fix some memory leaking bugs.
|
||||
- New API version() returns combined version.
|
||||
- Support diet mode.
|
||||
- Better support for detail option.
|
||||
|
||||
|
||||
[ Miscellaneous ]
|
||||
|
||||
- make.sh now can uninstall the core engine. This is done with:
|
||||
|
||||
$ sudo ./make.sh uninstall
|
||||
|
||||
----------------------------------
|
||||
Version 2.0: January 22nd, 2014
|
||||
|
||||
Release 2.0 deprecates verison 1.0 and brings a lot of crucial changes.
|
||||
|
||||
[ API changes ]
|
||||
|
||||
- API version has been bumped to 2.0 (see cs_version() API)
|
||||
- New API cs_strerror(errno) returns a string describing error code given
|
||||
in its only argument.
|
||||
- cs_version() now returns combined version encoding both major & minor versions.
|
||||
- New option CS_OPT_MODE allows to change engine’s mode at run-time with
|
||||
cs_option().
|
||||
- New option CS_OPT_MEM allows to specify user-defined functions for dynamically
|
||||
memory management used internally by Capstone. This is useful to embed Capstone
|
||||
into special environments such as kernel or firware.
|
||||
- New API cs_support() can be used to check if this lib supports a particular
|
||||
architecture (this is necessary since we now allow to choose which architectures
|
||||
to compile in).
|
||||
- The detail option is OFF by default now. To get detail information, it should be
|
||||
explicitly turned ON. The details then can be accessed using cs_insn.detail
|
||||
pointer (to newly added structure cs_detail)
|
||||
|
||||
|
||||
[ Core changes ]
|
||||
|
||||
- On memory usage, Capstone uses much less memory, but a lot faster now.
|
||||
- User now can choose which architectures to be supported by modifying config.mk
|
||||
before compiling/installing.
|
||||
|
||||
|
||||
[ Architectures ]
|
||||
|
||||
- Arm
|
||||
- Support Big-Endian mode (besides Little-Endian mode).
|
||||
- Support friendly register, so instead of output sub "r12,r11,0x14",
|
||||
we have "sub ip,fp,0x14".
|
||||
- Arm64: support Big-Endian mode (besides Little-Endian mode).
|
||||
- PowerPC: newly added.
|
||||
- Mips: support friendly register, so instead of output "srl $2,$1,0x1f",
|
||||
we have "srl $v0,$at,0x1f".
|
||||
- X86: bug fixes.
|
||||
|
||||
|
||||
[ Python binding ]
|
||||
|
||||
- Python binding is vastly improved in performance: around 3 ~ 4 times faster
|
||||
than in 1.0.
|
||||
- Cython support has been added, which can further speed up over the default
|
||||
pure Python binding (up to 30% in some cases)
|
||||
- Function cs_disasm_quick() & Cs.disasm() now use generator (rather than a list)
|
||||
to return succesfully disassembled instructions. This improves the performance
|
||||
and reduces memory usage.
|
||||
|
||||
|
||||
[ Java binding ]
|
||||
|
||||
- Better performance & bug fixes.
|
||||
|
||||
|
||||
[ Miscellaneous ]
|
||||
|
||||
- Fixed some installation issues with Gentoo Linux.
|
||||
- Capstone now can easily compile/install on all *nix, including Linux, OSX,
|
||||
{Net, Free, Open}BSD & Solaris.
|
||||
|
||||
----------------------------------
|
||||
[Version 1.0]: December 18th, 2013
|
||||
|
||||
- Initial public release.
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
This is the software license for Capstone disassembly framework.
|
||||
Capstone has been designed & implemented by Nguyen Anh Quynh <aquynh@gmail.com>
|
||||
|
||||
See http://www.capstone-engine.org for further information.
|
||||
|
||||
Copyright (c) 2013, COSEINC.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of the developer(s) nor the names of its
|
||||
contributors may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -0,0 +1,71 @@
|
||||
==============================================================================
|
||||
LLVM Release License
|
||||
==============================================================================
|
||||
University of Illinois/NCSA
|
||||
Open Source License
|
||||
|
||||
Copyright (c) 2003-2013 University of Illinois at Urbana-Champaign.
|
||||
All rights reserved.
|
||||
|
||||
Developed by:
|
||||
|
||||
LLVM Team
|
||||
|
||||
University of Illinois at Urbana-Champaign
|
||||
|
||||
http://llvm.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal with
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimers.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimers in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the names of the LLVM Team, University of Illinois at
|
||||
Urbana-Champaign, nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this Software without specific
|
||||
prior written permission.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
|
||||
SOFTWARE.
|
||||
|
||||
==============================================================================
|
||||
Copyrights and Licenses for Third Party Software Distributed with LLVM:
|
||||
==============================================================================
|
||||
The LLVM software contains code written by third parties. Such software will
|
||||
have its own individual LICENSE.TXT file in the directory in which it appears.
|
||||
This file will describe the copyrights, license, and restrictions which apply
|
||||
to that code.
|
||||
|
||||
The disclaimer of warranty in the University of Illinois Open Source License
|
||||
applies to all code in the LLVM Distribution, and nothing in any of the
|
||||
other licenses gives permission to use the names of the LLVM Team or the
|
||||
University of Illinois to endorse or promote products derived from this
|
||||
Software.
|
||||
|
||||
The following pieces of software have additional or alternate copyrights,
|
||||
licenses, and/or restrictions:
|
||||
|
||||
Program Directory
|
||||
------- ---------
|
||||
Autoconf llvm/autoconf
|
||||
llvm/projects/ModuleMaker/autoconf
|
||||
llvm/projects/sample/autoconf
|
||||
Google Test llvm/utils/unittest/googletest
|
||||
OpenBSD regex llvm/lib/Support/{reg*, COPYRIGHT.regex}
|
||||
pyyaml tests llvm/test/YAMLParser/{*.data, LICENSE.TXT}
|
||||
ARM contributions llvm/lib/Target/ARM/LICENSE.TXT
|
||||
md5 contributions llvm/lib/Support/MD5.cpp llvm/include/llvm/Support/MD5.h
|
||||
@@ -0,0 +1,65 @@
|
||||
Capstone Engine
|
||||
===============
|
||||
|
||||
[](https://travis-ci.org/aquynh/capstone)
|
||||
[](https://ci.appveyor.com/project/aquynh/capstone/branch/next)
|
||||
|
||||
Capstone is a disassembly framework with the target of becoming the ultimate
|
||||
disasm engine for binary analysis and reversing in the security community.
|
||||
|
||||
Created by Nguyen Anh Quynh, then developed and maintained by a small community,
|
||||
Capstone offers some unparalleled features:
|
||||
|
||||
- Support multiple hardware architectures: ARM, ARM64 (ARMv8), Ethereum VM, M68K,
|
||||
Mips, PPC, Sparc, SystemZ, TMS320C64X, M680X, XCore and X86 (including X86_64).
|
||||
|
||||
- Having clean/simple/lightweight/intuitive architecture-neutral API.
|
||||
|
||||
- Provide details on disassembled instruction (called “decomposer” by others).
|
||||
|
||||
- Provide semantics of the disassembled instruction, such as list of implicit
|
||||
registers read & written.
|
||||
|
||||
- Implemented in pure C language, with lightweight bindings for D, Clojure, F#,
|
||||
Common Lisp, Visual Basic, PHP, PowerShell, Emacs, Haskell, Perl, Python,
|
||||
Ruby, C#, NodeJS, Java, GO, C++, OCaml, Lua, Rust, Delphi, Free Pascal & Vala
|
||||
ready either in main code, or provided externally by the community).
|
||||
|
||||
- Native support for all popular platforms: Windows, Mac OSX, iOS, Android,
|
||||
Linux, \*BSD, Solaris, etc.
|
||||
|
||||
- Thread-safe by design.
|
||||
|
||||
- Special support for embedding into firmware or OS kernel.
|
||||
|
||||
- High performance & suitable for malware analysis (capable of handling various
|
||||
X86 malware tricks).
|
||||
|
||||
- Distributed under the open source BSD license.
|
||||
|
||||
Further information is available at http://www.capstone-engine.org
|
||||
|
||||
|
||||
Compile
|
||||
-------
|
||||
|
||||
See COMPILE.TXT file for how to compile and install Capstone.
|
||||
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
See docs/README for how to customize & program your own tools with Capstone.
|
||||
|
||||
|
||||
Hack
|
||||
----
|
||||
|
||||
See HACK.TXT file for the structure of the source code.
|
||||
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
This project is released under the BSD license. If you redistribute the binary
|
||||
or source code of Capstone, please attach file LICENSE.TXT with your products.
|
||||
@@ -0,0 +1,20 @@
|
||||
* Version 4.0.1 - January 10th, 2019
|
||||
|
||||
Release 4.0.1 was sponsored by the following companies (in no particular order).
|
||||
|
||||
- NowSecure: https://www.nowsecure.com
|
||||
- Verichains: https://verichains.io
|
||||
- Vsec: https://vsec.com.vn
|
||||
|
||||
-----------------------------------
|
||||
* Version 4.0 - December 18th, 2018
|
||||
|
||||
Capstone 4.0 version marks 5 years of the project!
|
||||
This release was sponsored by the following companies (in no particular order).
|
||||
|
||||
- Thinkst Canary: https://canary.tools
|
||||
- NowSecure: https://www.nowsecure.com
|
||||
- ECQ: https://e-cq.net
|
||||
- Senrio: https://senr.io
|
||||
- GracefulBits: https://gracefulbits.com
|
||||
- Catena Cyber: https://catenacyber.fr
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,937 @@
|
||||
#ifndef CAPSTONE_ARM_H
|
||||
#define CAPSTONE_ARM_H
|
||||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
/// ARM shift type
|
||||
typedef enum arm_shifter {
|
||||
ARM_SFT_INVALID = 0,
|
||||
ARM_SFT_ASR, ///< shift with immediate const
|
||||
ARM_SFT_LSL, ///< shift with immediate const
|
||||
ARM_SFT_LSR, ///< shift with immediate const
|
||||
ARM_SFT_ROR, ///< shift with immediate const
|
||||
ARM_SFT_RRX, ///< shift with immediate const
|
||||
ARM_SFT_ASR_REG, ///< shift with register
|
||||
ARM_SFT_LSL_REG, ///< shift with register
|
||||
ARM_SFT_LSR_REG, ///< shift with register
|
||||
ARM_SFT_ROR_REG, ///< shift with register
|
||||
ARM_SFT_RRX_REG, ///< shift with register
|
||||
} arm_shifter;
|
||||
|
||||
/// ARM condition code
|
||||
typedef enum arm_cc {
|
||||
ARM_CC_INVALID = 0,
|
||||
ARM_CC_EQ, ///< Equal Equal
|
||||
ARM_CC_NE, ///< Not equal Not equal, or unordered
|
||||
ARM_CC_HS, ///< Carry set >, ==, or unordered
|
||||
ARM_CC_LO, ///< Carry clear Less than
|
||||
ARM_CC_MI, ///< Minus, negative Less than
|
||||
ARM_CC_PL, ///< Plus, positive or zero >, ==, or unordered
|
||||
ARM_CC_VS, ///< Overflow Unordered
|
||||
ARM_CC_VC, ///< No overflow Not unordered
|
||||
ARM_CC_HI, ///< Unsigned higher Greater than, or unordered
|
||||
ARM_CC_LS, ///< Unsigned lower or same Less than or equal
|
||||
ARM_CC_GE, ///< Greater than or equal Greater than or equal
|
||||
ARM_CC_LT, ///< Less than Less than, or unordered
|
||||
ARM_CC_GT, ///< Greater than Greater than
|
||||
ARM_CC_LE, ///< Less than or equal <, ==, or unordered
|
||||
ARM_CC_AL ///< Always (unconditional) Always (unconditional)
|
||||
} arm_cc;
|
||||
|
||||
typedef enum arm_sysreg {
|
||||
/// Special registers for MSR
|
||||
ARM_SYSREG_INVALID = 0,
|
||||
|
||||
// SPSR* registers can be OR combined
|
||||
ARM_SYSREG_SPSR_C = 1,
|
||||
ARM_SYSREG_SPSR_X = 2,
|
||||
ARM_SYSREG_SPSR_S = 4,
|
||||
ARM_SYSREG_SPSR_F = 8,
|
||||
|
||||
// CPSR* registers can be OR combined
|
||||
ARM_SYSREG_CPSR_C = 16,
|
||||
ARM_SYSREG_CPSR_X = 32,
|
||||
ARM_SYSREG_CPSR_S = 64,
|
||||
ARM_SYSREG_CPSR_F = 128,
|
||||
|
||||
// independent registers
|
||||
ARM_SYSREG_APSR = 256,
|
||||
ARM_SYSREG_APSR_G,
|
||||
ARM_SYSREG_APSR_NZCVQ,
|
||||
ARM_SYSREG_APSR_NZCVQG,
|
||||
|
||||
ARM_SYSREG_IAPSR,
|
||||
ARM_SYSREG_IAPSR_G,
|
||||
ARM_SYSREG_IAPSR_NZCVQG,
|
||||
ARM_SYSREG_IAPSR_NZCVQ,
|
||||
|
||||
ARM_SYSREG_EAPSR,
|
||||
ARM_SYSREG_EAPSR_G,
|
||||
ARM_SYSREG_EAPSR_NZCVQG,
|
||||
ARM_SYSREG_EAPSR_NZCVQ,
|
||||
|
||||
ARM_SYSREG_XPSR,
|
||||
ARM_SYSREG_XPSR_G,
|
||||
ARM_SYSREG_XPSR_NZCVQG,
|
||||
ARM_SYSREG_XPSR_NZCVQ,
|
||||
|
||||
ARM_SYSREG_IPSR,
|
||||
ARM_SYSREG_EPSR,
|
||||
ARM_SYSREG_IEPSR,
|
||||
|
||||
ARM_SYSREG_MSP,
|
||||
ARM_SYSREG_PSP,
|
||||
ARM_SYSREG_PRIMASK,
|
||||
ARM_SYSREG_BASEPRI,
|
||||
ARM_SYSREG_BASEPRI_MAX,
|
||||
ARM_SYSREG_FAULTMASK,
|
||||
ARM_SYSREG_CONTROL,
|
||||
|
||||
// Banked Registers
|
||||
ARM_SYSREG_R8_USR,
|
||||
ARM_SYSREG_R9_USR,
|
||||
ARM_SYSREG_R10_USR,
|
||||
ARM_SYSREG_R11_USR,
|
||||
ARM_SYSREG_R12_USR,
|
||||
ARM_SYSREG_SP_USR,
|
||||
ARM_SYSREG_LR_USR,
|
||||
ARM_SYSREG_R8_FIQ,
|
||||
ARM_SYSREG_R9_FIQ,
|
||||
ARM_SYSREG_R10_FIQ,
|
||||
ARM_SYSREG_R11_FIQ,
|
||||
ARM_SYSREG_R12_FIQ,
|
||||
ARM_SYSREG_SP_FIQ,
|
||||
ARM_SYSREG_LR_FIQ,
|
||||
ARM_SYSREG_LR_IRQ,
|
||||
ARM_SYSREG_SP_IRQ,
|
||||
ARM_SYSREG_LR_SVC,
|
||||
ARM_SYSREG_SP_SVC,
|
||||
ARM_SYSREG_LR_ABT,
|
||||
ARM_SYSREG_SP_ABT,
|
||||
ARM_SYSREG_LR_UND,
|
||||
ARM_SYSREG_SP_UND,
|
||||
ARM_SYSREG_LR_MON,
|
||||
ARM_SYSREG_SP_MON,
|
||||
ARM_SYSREG_ELR_HYP,
|
||||
ARM_SYSREG_SP_HYP,
|
||||
|
||||
ARM_SYSREG_SPSR_FIQ,
|
||||
ARM_SYSREG_SPSR_IRQ,
|
||||
ARM_SYSREG_SPSR_SVC,
|
||||
ARM_SYSREG_SPSR_ABT,
|
||||
ARM_SYSREG_SPSR_UND,
|
||||
ARM_SYSREG_SPSR_MON,
|
||||
ARM_SYSREG_SPSR_HYP,
|
||||
} arm_sysreg;
|
||||
|
||||
/// The memory barrier constants map directly to the 4-bit encoding of
|
||||
/// the option field for Memory Barrier operations.
|
||||
typedef enum arm_mem_barrier {
|
||||
ARM_MB_INVALID = 0,
|
||||
ARM_MB_RESERVED_0,
|
||||
ARM_MB_OSHLD,
|
||||
ARM_MB_OSHST,
|
||||
ARM_MB_OSH,
|
||||
ARM_MB_RESERVED_4,
|
||||
ARM_MB_NSHLD,
|
||||
ARM_MB_NSHST,
|
||||
ARM_MB_NSH,
|
||||
ARM_MB_RESERVED_8,
|
||||
ARM_MB_ISHLD,
|
||||
ARM_MB_ISHST,
|
||||
ARM_MB_ISH,
|
||||
ARM_MB_RESERVED_12,
|
||||
ARM_MB_LD,
|
||||
ARM_MB_ST,
|
||||
ARM_MB_SY,
|
||||
} arm_mem_barrier;
|
||||
|
||||
/// Operand type for instruction's operands
|
||||
typedef enum arm_op_type {
|
||||
ARM_OP_INVALID = 0, ///< = CS_OP_INVALID (Uninitialized).
|
||||
ARM_OP_REG, ///< = CS_OP_REG (Register operand).
|
||||
ARM_OP_IMM, ///< = CS_OP_IMM (Immediate operand).
|
||||
ARM_OP_MEM, ///< = CS_OP_MEM (Memory operand).
|
||||
ARM_OP_FP, ///< = CS_OP_FP (Floating-Point operand).
|
||||
ARM_OP_CIMM = 64, ///< C-Immediate (coprocessor registers)
|
||||
ARM_OP_PIMM, ///< P-Immediate (coprocessor registers)
|
||||
ARM_OP_SETEND, ///< operand for SETEND instruction
|
||||
ARM_OP_SYSREG, ///< MSR/MRS special register operand
|
||||
} arm_op_type;
|
||||
|
||||
/// Operand type for SETEND instruction
|
||||
typedef enum arm_setend_type {
|
||||
ARM_SETEND_INVALID = 0, ///< Uninitialized.
|
||||
ARM_SETEND_BE, ///< BE operand.
|
||||
ARM_SETEND_LE, ///< LE operand
|
||||
} arm_setend_type;
|
||||
|
||||
typedef enum arm_cpsmode_type {
|
||||
ARM_CPSMODE_INVALID = 0,
|
||||
ARM_CPSMODE_IE = 2,
|
||||
ARM_CPSMODE_ID = 3
|
||||
} arm_cpsmode_type;
|
||||
|
||||
/// Operand type for SETEND instruction
|
||||
typedef enum arm_cpsflag_type {
|
||||
ARM_CPSFLAG_INVALID = 0,
|
||||
ARM_CPSFLAG_F = 1,
|
||||
ARM_CPSFLAG_I = 2,
|
||||
ARM_CPSFLAG_A = 4,
|
||||
ARM_CPSFLAG_NONE = 16, ///< no flag
|
||||
} arm_cpsflag_type;
|
||||
|
||||
/// Data type for elements of vector instructions.
|
||||
typedef enum arm_vectordata_type {
|
||||
ARM_VECTORDATA_INVALID = 0,
|
||||
|
||||
// Integer type
|
||||
ARM_VECTORDATA_I8,
|
||||
ARM_VECTORDATA_I16,
|
||||
ARM_VECTORDATA_I32,
|
||||
ARM_VECTORDATA_I64,
|
||||
|
||||
// Signed integer type
|
||||
ARM_VECTORDATA_S8,
|
||||
ARM_VECTORDATA_S16,
|
||||
ARM_VECTORDATA_S32,
|
||||
ARM_VECTORDATA_S64,
|
||||
|
||||
// Unsigned integer type
|
||||
ARM_VECTORDATA_U8,
|
||||
ARM_VECTORDATA_U16,
|
||||
ARM_VECTORDATA_U32,
|
||||
ARM_VECTORDATA_U64,
|
||||
|
||||
// Data type for VMUL/VMULL
|
||||
ARM_VECTORDATA_P8,
|
||||
|
||||
// Floating type
|
||||
ARM_VECTORDATA_F32,
|
||||
ARM_VECTORDATA_F64,
|
||||
|
||||
// Convert float <-> float
|
||||
ARM_VECTORDATA_F16F64, // f16.f64
|
||||
ARM_VECTORDATA_F64F16, // f64.f16
|
||||
ARM_VECTORDATA_F32F16, // f32.f16
|
||||
ARM_VECTORDATA_F16F32, // f32.f16
|
||||
ARM_VECTORDATA_F64F32, // f64.f32
|
||||
ARM_VECTORDATA_F32F64, // f32.f64
|
||||
|
||||
// Convert integer <-> float
|
||||
ARM_VECTORDATA_S32F32, // s32.f32
|
||||
ARM_VECTORDATA_U32F32, // u32.f32
|
||||
ARM_VECTORDATA_F32S32, // f32.s32
|
||||
ARM_VECTORDATA_F32U32, // f32.u32
|
||||
ARM_VECTORDATA_F64S16, // f64.s16
|
||||
ARM_VECTORDATA_F32S16, // f32.s16
|
||||
ARM_VECTORDATA_F64S32, // f64.s32
|
||||
ARM_VECTORDATA_S16F64, // s16.f64
|
||||
ARM_VECTORDATA_S16F32, // s16.f64
|
||||
ARM_VECTORDATA_S32F64, // s32.f64
|
||||
ARM_VECTORDATA_U16F64, // u16.f64
|
||||
ARM_VECTORDATA_U16F32, // u16.f32
|
||||
ARM_VECTORDATA_U32F64, // u32.f64
|
||||
ARM_VECTORDATA_F64U16, // f64.u16
|
||||
ARM_VECTORDATA_F32U16, // f32.u16
|
||||
ARM_VECTORDATA_F64U32, // f64.u32
|
||||
} arm_vectordata_type;
|
||||
|
||||
/// ARM registers
|
||||
typedef enum arm_reg {
|
||||
ARM_REG_INVALID = 0,
|
||||
ARM_REG_APSR,
|
||||
ARM_REG_APSR_NZCV,
|
||||
ARM_REG_CPSR,
|
||||
ARM_REG_FPEXC,
|
||||
ARM_REG_FPINST,
|
||||
ARM_REG_FPSCR,
|
||||
ARM_REG_FPSCR_NZCV,
|
||||
ARM_REG_FPSID,
|
||||
ARM_REG_ITSTATE,
|
||||
ARM_REG_LR,
|
||||
ARM_REG_PC,
|
||||
ARM_REG_SP,
|
||||
ARM_REG_SPSR,
|
||||
ARM_REG_D0,
|
||||
ARM_REG_D1,
|
||||
ARM_REG_D2,
|
||||
ARM_REG_D3,
|
||||
ARM_REG_D4,
|
||||
ARM_REG_D5,
|
||||
ARM_REG_D6,
|
||||
ARM_REG_D7,
|
||||
ARM_REG_D8,
|
||||
ARM_REG_D9,
|
||||
ARM_REG_D10,
|
||||
ARM_REG_D11,
|
||||
ARM_REG_D12,
|
||||
ARM_REG_D13,
|
||||
ARM_REG_D14,
|
||||
ARM_REG_D15,
|
||||
ARM_REG_D16,
|
||||
ARM_REG_D17,
|
||||
ARM_REG_D18,
|
||||
ARM_REG_D19,
|
||||
ARM_REG_D20,
|
||||
ARM_REG_D21,
|
||||
ARM_REG_D22,
|
||||
ARM_REG_D23,
|
||||
ARM_REG_D24,
|
||||
ARM_REG_D25,
|
||||
ARM_REG_D26,
|
||||
ARM_REG_D27,
|
||||
ARM_REG_D28,
|
||||
ARM_REG_D29,
|
||||
ARM_REG_D30,
|
||||
ARM_REG_D31,
|
||||
ARM_REG_FPINST2,
|
||||
ARM_REG_MVFR0,
|
||||
ARM_REG_MVFR1,
|
||||
ARM_REG_MVFR2,
|
||||
ARM_REG_Q0,
|
||||
ARM_REG_Q1,
|
||||
ARM_REG_Q2,
|
||||
ARM_REG_Q3,
|
||||
ARM_REG_Q4,
|
||||
ARM_REG_Q5,
|
||||
ARM_REG_Q6,
|
||||
ARM_REG_Q7,
|
||||
ARM_REG_Q8,
|
||||
ARM_REG_Q9,
|
||||
ARM_REG_Q10,
|
||||
ARM_REG_Q11,
|
||||
ARM_REG_Q12,
|
||||
ARM_REG_Q13,
|
||||
ARM_REG_Q14,
|
||||
ARM_REG_Q15,
|
||||
ARM_REG_R0,
|
||||
ARM_REG_R1,
|
||||
ARM_REG_R2,
|
||||
ARM_REG_R3,
|
||||
ARM_REG_R4,
|
||||
ARM_REG_R5,
|
||||
ARM_REG_R6,
|
||||
ARM_REG_R7,
|
||||
ARM_REG_R8,
|
||||
ARM_REG_R9,
|
||||
ARM_REG_R10,
|
||||
ARM_REG_R11,
|
||||
ARM_REG_R12,
|
||||
ARM_REG_S0,
|
||||
ARM_REG_S1,
|
||||
ARM_REG_S2,
|
||||
ARM_REG_S3,
|
||||
ARM_REG_S4,
|
||||
ARM_REG_S5,
|
||||
ARM_REG_S6,
|
||||
ARM_REG_S7,
|
||||
ARM_REG_S8,
|
||||
ARM_REG_S9,
|
||||
ARM_REG_S10,
|
||||
ARM_REG_S11,
|
||||
ARM_REG_S12,
|
||||
ARM_REG_S13,
|
||||
ARM_REG_S14,
|
||||
ARM_REG_S15,
|
||||
ARM_REG_S16,
|
||||
ARM_REG_S17,
|
||||
ARM_REG_S18,
|
||||
ARM_REG_S19,
|
||||
ARM_REG_S20,
|
||||
ARM_REG_S21,
|
||||
ARM_REG_S22,
|
||||
ARM_REG_S23,
|
||||
ARM_REG_S24,
|
||||
ARM_REG_S25,
|
||||
ARM_REG_S26,
|
||||
ARM_REG_S27,
|
||||
ARM_REG_S28,
|
||||
ARM_REG_S29,
|
||||
ARM_REG_S30,
|
||||
ARM_REG_S31,
|
||||
|
||||
ARM_REG_ENDING, // <-- mark the end of the list or registers
|
||||
|
||||
// alias registers
|
||||
ARM_REG_R13 = ARM_REG_SP,
|
||||
ARM_REG_R14 = ARM_REG_LR,
|
||||
ARM_REG_R15 = ARM_REG_PC,
|
||||
|
||||
ARM_REG_SB = ARM_REG_R9,
|
||||
ARM_REG_SL = ARM_REG_R10,
|
||||
ARM_REG_FP = ARM_REG_R11,
|
||||
ARM_REG_IP = ARM_REG_R12,
|
||||
} arm_reg;
|
||||
|
||||
/// Instruction's operand referring to memory
|
||||
/// This is associated with ARM_OP_MEM operand type above
|
||||
typedef struct arm_op_mem {
|
||||
arm_reg base; ///< base register
|
||||
arm_reg index; ///< index register
|
||||
int scale; ///< scale for index register (can be 1, or -1)
|
||||
int disp; ///< displacement/offset value
|
||||
/// left-shift on index register, or 0 if irrelevant
|
||||
/// NOTE: this value can also be fetched via operand.shift.value
|
||||
int lshift;
|
||||
} arm_op_mem;
|
||||
|
||||
/// Instruction operand
|
||||
typedef struct cs_arm_op {
|
||||
int vector_index; ///< Vector Index for some vector operands (or -1 if irrelevant)
|
||||
|
||||
struct {
|
||||
arm_shifter type;
|
||||
unsigned int value;
|
||||
} shift;
|
||||
|
||||
arm_op_type type; ///< operand type
|
||||
|
||||
union {
|
||||
int reg; ///< register value for REG/SYSREG operand
|
||||
int32_t imm; ///< immediate value for C-IMM, P-IMM or IMM operand
|
||||
double fp; ///< floating point value for FP operand
|
||||
arm_op_mem mem; ///< base/index/scale/disp value for MEM operand
|
||||
arm_setend_type setend; ///< SETEND instruction's operand type
|
||||
};
|
||||
|
||||
/// in some instructions, an operand can be subtracted or added to
|
||||
/// the base register,
|
||||
/// if TRUE, this operand is subtracted. otherwise, it is added.
|
||||
bool subtracted;
|
||||
|
||||
/// How is this operand accessed? (READ, WRITE or READ|WRITE)
|
||||
/// This field is combined of cs_ac_type.
|
||||
/// NOTE: this field is irrelevant if engine is compiled in DIET mode.
|
||||
uint8_t access;
|
||||
|
||||
/// Neon lane index for NEON instructions (or -1 if irrelevant)
|
||||
int8_t neon_lane;
|
||||
} cs_arm_op;
|
||||
|
||||
/// Instruction structure
|
||||
typedef struct cs_arm {
|
||||
bool usermode; ///< User-mode registers to be loaded (for LDM/STM instructions)
|
||||
int vector_size; ///< Scalar size for vector instructions
|
||||
arm_vectordata_type vector_data; ///< Data type for elements of vector instructions
|
||||
arm_cpsmode_type cps_mode; ///< CPS mode for CPS instruction
|
||||
arm_cpsflag_type cps_flag; ///< CPS mode for CPS instruction
|
||||
arm_cc cc; ///< conditional code for this insn
|
||||
bool update_flags; ///< does this insn update flags?
|
||||
bool writeback; ///< does this insn write-back?
|
||||
arm_mem_barrier mem_barrier; ///< Option for some memory barrier instructions
|
||||
|
||||
/// Number of operands of this instruction,
|
||||
/// or 0 when instruction has no operand.
|
||||
uint8_t op_count;
|
||||
|
||||
cs_arm_op operands[36]; ///< operands for this instruction.
|
||||
} cs_arm;
|
||||
|
||||
/// ARM instruction
|
||||
typedef enum arm_insn {
|
||||
ARM_INS_INVALID = 0,
|
||||
|
||||
ARM_INS_ADC,
|
||||
ARM_INS_ADD,
|
||||
ARM_INS_ADR,
|
||||
ARM_INS_AESD,
|
||||
ARM_INS_AESE,
|
||||
ARM_INS_AESIMC,
|
||||
ARM_INS_AESMC,
|
||||
ARM_INS_AND,
|
||||
ARM_INS_BFC,
|
||||
ARM_INS_BFI,
|
||||
ARM_INS_BIC,
|
||||
ARM_INS_BKPT,
|
||||
ARM_INS_BL,
|
||||
ARM_INS_BLX,
|
||||
ARM_INS_BX,
|
||||
ARM_INS_BXJ,
|
||||
ARM_INS_B,
|
||||
ARM_INS_CDP,
|
||||
ARM_INS_CDP2,
|
||||
ARM_INS_CLREX,
|
||||
ARM_INS_CLZ,
|
||||
ARM_INS_CMN,
|
||||
ARM_INS_CMP,
|
||||
ARM_INS_CPS,
|
||||
ARM_INS_CRC32B,
|
||||
ARM_INS_CRC32CB,
|
||||
ARM_INS_CRC32CH,
|
||||
ARM_INS_CRC32CW,
|
||||
ARM_INS_CRC32H,
|
||||
ARM_INS_CRC32W,
|
||||
ARM_INS_DBG,
|
||||
ARM_INS_DMB,
|
||||
ARM_INS_DSB,
|
||||
ARM_INS_EOR,
|
||||
ARM_INS_ERET,
|
||||
ARM_INS_VMOV,
|
||||
ARM_INS_FLDMDBX,
|
||||
ARM_INS_FLDMIAX,
|
||||
ARM_INS_VMRS,
|
||||
ARM_INS_FSTMDBX,
|
||||
ARM_INS_FSTMIAX,
|
||||
ARM_INS_HINT,
|
||||
ARM_INS_HLT,
|
||||
ARM_INS_HVC,
|
||||
ARM_INS_ISB,
|
||||
ARM_INS_LDA,
|
||||
ARM_INS_LDAB,
|
||||
ARM_INS_LDAEX,
|
||||
ARM_INS_LDAEXB,
|
||||
ARM_INS_LDAEXD,
|
||||
ARM_INS_LDAEXH,
|
||||
ARM_INS_LDAH,
|
||||
ARM_INS_LDC2L,
|
||||
ARM_INS_LDC2,
|
||||
ARM_INS_LDCL,
|
||||
ARM_INS_LDC,
|
||||
ARM_INS_LDMDA,
|
||||
ARM_INS_LDMDB,
|
||||
ARM_INS_LDM,
|
||||
ARM_INS_LDMIB,
|
||||
ARM_INS_LDRBT,
|
||||
ARM_INS_LDRB,
|
||||
ARM_INS_LDRD,
|
||||
ARM_INS_LDREX,
|
||||
ARM_INS_LDREXB,
|
||||
ARM_INS_LDREXD,
|
||||
ARM_INS_LDREXH,
|
||||
ARM_INS_LDRH,
|
||||
ARM_INS_LDRHT,
|
||||
ARM_INS_LDRSB,
|
||||
ARM_INS_LDRSBT,
|
||||
ARM_INS_LDRSH,
|
||||
ARM_INS_LDRSHT,
|
||||
ARM_INS_LDRT,
|
||||
ARM_INS_LDR,
|
||||
ARM_INS_MCR,
|
||||
ARM_INS_MCR2,
|
||||
ARM_INS_MCRR,
|
||||
ARM_INS_MCRR2,
|
||||
ARM_INS_MLA,
|
||||
ARM_INS_MLS,
|
||||
ARM_INS_MOV,
|
||||
ARM_INS_MOVT,
|
||||
ARM_INS_MOVW,
|
||||
ARM_INS_MRC,
|
||||
ARM_INS_MRC2,
|
||||
ARM_INS_MRRC,
|
||||
ARM_INS_MRRC2,
|
||||
ARM_INS_MRS,
|
||||
ARM_INS_MSR,
|
||||
ARM_INS_MUL,
|
||||
ARM_INS_MVN,
|
||||
ARM_INS_ORR,
|
||||
ARM_INS_PKHBT,
|
||||
ARM_INS_PKHTB,
|
||||
ARM_INS_PLDW,
|
||||
ARM_INS_PLD,
|
||||
ARM_INS_PLI,
|
||||
ARM_INS_QADD,
|
||||
ARM_INS_QADD16,
|
||||
ARM_INS_QADD8,
|
||||
ARM_INS_QASX,
|
||||
ARM_INS_QDADD,
|
||||
ARM_INS_QDSUB,
|
||||
ARM_INS_QSAX,
|
||||
ARM_INS_QSUB,
|
||||
ARM_INS_QSUB16,
|
||||
ARM_INS_QSUB8,
|
||||
ARM_INS_RBIT,
|
||||
ARM_INS_REV,
|
||||
ARM_INS_REV16,
|
||||
ARM_INS_REVSH,
|
||||
ARM_INS_RFEDA,
|
||||
ARM_INS_RFEDB,
|
||||
ARM_INS_RFEIA,
|
||||
ARM_INS_RFEIB,
|
||||
ARM_INS_RSB,
|
||||
ARM_INS_RSC,
|
||||
ARM_INS_SADD16,
|
||||
ARM_INS_SADD8,
|
||||
ARM_INS_SASX,
|
||||
ARM_INS_SBC,
|
||||
ARM_INS_SBFX,
|
||||
ARM_INS_SDIV,
|
||||
ARM_INS_SEL,
|
||||
ARM_INS_SETEND,
|
||||
ARM_INS_SHA1C,
|
||||
ARM_INS_SHA1H,
|
||||
ARM_INS_SHA1M,
|
||||
ARM_INS_SHA1P,
|
||||
ARM_INS_SHA1SU0,
|
||||
ARM_INS_SHA1SU1,
|
||||
ARM_INS_SHA256H,
|
||||
ARM_INS_SHA256H2,
|
||||
ARM_INS_SHA256SU0,
|
||||
ARM_INS_SHA256SU1,
|
||||
ARM_INS_SHADD16,
|
||||
ARM_INS_SHADD8,
|
||||
ARM_INS_SHASX,
|
||||
ARM_INS_SHSAX,
|
||||
ARM_INS_SHSUB16,
|
||||
ARM_INS_SHSUB8,
|
||||
ARM_INS_SMC,
|
||||
ARM_INS_SMLABB,
|
||||
ARM_INS_SMLABT,
|
||||
ARM_INS_SMLAD,
|
||||
ARM_INS_SMLADX,
|
||||
ARM_INS_SMLAL,
|
||||
ARM_INS_SMLALBB,
|
||||
ARM_INS_SMLALBT,
|
||||
ARM_INS_SMLALD,
|
||||
ARM_INS_SMLALDX,
|
||||
ARM_INS_SMLALTB,
|
||||
ARM_INS_SMLALTT,
|
||||
ARM_INS_SMLATB,
|
||||
ARM_INS_SMLATT,
|
||||
ARM_INS_SMLAWB,
|
||||
ARM_INS_SMLAWT,
|
||||
ARM_INS_SMLSD,
|
||||
ARM_INS_SMLSDX,
|
||||
ARM_INS_SMLSLD,
|
||||
ARM_INS_SMLSLDX,
|
||||
ARM_INS_SMMLA,
|
||||
ARM_INS_SMMLAR,
|
||||
ARM_INS_SMMLS,
|
||||
ARM_INS_SMMLSR,
|
||||
ARM_INS_SMMUL,
|
||||
ARM_INS_SMMULR,
|
||||
ARM_INS_SMUAD,
|
||||
ARM_INS_SMUADX,
|
||||
ARM_INS_SMULBB,
|
||||
ARM_INS_SMULBT,
|
||||
ARM_INS_SMULL,
|
||||
ARM_INS_SMULTB,
|
||||
ARM_INS_SMULTT,
|
||||
ARM_INS_SMULWB,
|
||||
ARM_INS_SMULWT,
|
||||
ARM_INS_SMUSD,
|
||||
ARM_INS_SMUSDX,
|
||||
ARM_INS_SRSDA,
|
||||
ARM_INS_SRSDB,
|
||||
ARM_INS_SRSIA,
|
||||
ARM_INS_SRSIB,
|
||||
ARM_INS_SSAT,
|
||||
ARM_INS_SSAT16,
|
||||
ARM_INS_SSAX,
|
||||
ARM_INS_SSUB16,
|
||||
ARM_INS_SSUB8,
|
||||
ARM_INS_STC2L,
|
||||
ARM_INS_STC2,
|
||||
ARM_INS_STCL,
|
||||
ARM_INS_STC,
|
||||
ARM_INS_STL,
|
||||
ARM_INS_STLB,
|
||||
ARM_INS_STLEX,
|
||||
ARM_INS_STLEXB,
|
||||
ARM_INS_STLEXD,
|
||||
ARM_INS_STLEXH,
|
||||
ARM_INS_STLH,
|
||||
ARM_INS_STMDA,
|
||||
ARM_INS_STMDB,
|
||||
ARM_INS_STM,
|
||||
ARM_INS_STMIB,
|
||||
ARM_INS_STRBT,
|
||||
ARM_INS_STRB,
|
||||
ARM_INS_STRD,
|
||||
ARM_INS_STREX,
|
||||
ARM_INS_STREXB,
|
||||
ARM_INS_STREXD,
|
||||
ARM_INS_STREXH,
|
||||
ARM_INS_STRH,
|
||||
ARM_INS_STRHT,
|
||||
ARM_INS_STRT,
|
||||
ARM_INS_STR,
|
||||
ARM_INS_SUB,
|
||||
ARM_INS_SVC,
|
||||
ARM_INS_SWP,
|
||||
ARM_INS_SWPB,
|
||||
ARM_INS_SXTAB,
|
||||
ARM_INS_SXTAB16,
|
||||
ARM_INS_SXTAH,
|
||||
ARM_INS_SXTB,
|
||||
ARM_INS_SXTB16,
|
||||
ARM_INS_SXTH,
|
||||
ARM_INS_TEQ,
|
||||
ARM_INS_TRAP,
|
||||
ARM_INS_TST,
|
||||
ARM_INS_UADD16,
|
||||
ARM_INS_UADD8,
|
||||
ARM_INS_UASX,
|
||||
ARM_INS_UBFX,
|
||||
ARM_INS_UDF,
|
||||
ARM_INS_UDIV,
|
||||
ARM_INS_UHADD16,
|
||||
ARM_INS_UHADD8,
|
||||
ARM_INS_UHASX,
|
||||
ARM_INS_UHSAX,
|
||||
ARM_INS_UHSUB16,
|
||||
ARM_INS_UHSUB8,
|
||||
ARM_INS_UMAAL,
|
||||
ARM_INS_UMLAL,
|
||||
ARM_INS_UMULL,
|
||||
ARM_INS_UQADD16,
|
||||
ARM_INS_UQADD8,
|
||||
ARM_INS_UQASX,
|
||||
ARM_INS_UQSAX,
|
||||
ARM_INS_UQSUB16,
|
||||
ARM_INS_UQSUB8,
|
||||
ARM_INS_USAD8,
|
||||
ARM_INS_USADA8,
|
||||
ARM_INS_USAT,
|
||||
ARM_INS_USAT16,
|
||||
ARM_INS_USAX,
|
||||
ARM_INS_USUB16,
|
||||
ARM_INS_USUB8,
|
||||
ARM_INS_UXTAB,
|
||||
ARM_INS_UXTAB16,
|
||||
ARM_INS_UXTAH,
|
||||
ARM_INS_UXTB,
|
||||
ARM_INS_UXTB16,
|
||||
ARM_INS_UXTH,
|
||||
ARM_INS_VABAL,
|
||||
ARM_INS_VABA,
|
||||
ARM_INS_VABDL,
|
||||
ARM_INS_VABD,
|
||||
ARM_INS_VABS,
|
||||
ARM_INS_VACGE,
|
||||
ARM_INS_VACGT,
|
||||
ARM_INS_VADD,
|
||||
ARM_INS_VADDHN,
|
||||
ARM_INS_VADDL,
|
||||
ARM_INS_VADDW,
|
||||
ARM_INS_VAND,
|
||||
ARM_INS_VBIC,
|
||||
ARM_INS_VBIF,
|
||||
ARM_INS_VBIT,
|
||||
ARM_INS_VBSL,
|
||||
ARM_INS_VCEQ,
|
||||
ARM_INS_VCGE,
|
||||
ARM_INS_VCGT,
|
||||
ARM_INS_VCLE,
|
||||
ARM_INS_VCLS,
|
||||
ARM_INS_VCLT,
|
||||
ARM_INS_VCLZ,
|
||||
ARM_INS_VCMP,
|
||||
ARM_INS_VCMPE,
|
||||
ARM_INS_VCNT,
|
||||
ARM_INS_VCVTA,
|
||||
ARM_INS_VCVTB,
|
||||
ARM_INS_VCVT,
|
||||
ARM_INS_VCVTM,
|
||||
ARM_INS_VCVTN,
|
||||
ARM_INS_VCVTP,
|
||||
ARM_INS_VCVTT,
|
||||
ARM_INS_VDIV,
|
||||
ARM_INS_VDUP,
|
||||
ARM_INS_VEOR,
|
||||
ARM_INS_VEXT,
|
||||
ARM_INS_VFMA,
|
||||
ARM_INS_VFMS,
|
||||
ARM_INS_VFNMA,
|
||||
ARM_INS_VFNMS,
|
||||
ARM_INS_VHADD,
|
||||
ARM_INS_VHSUB,
|
||||
ARM_INS_VLD1,
|
||||
ARM_INS_VLD2,
|
||||
ARM_INS_VLD3,
|
||||
ARM_INS_VLD4,
|
||||
ARM_INS_VLDMDB,
|
||||
ARM_INS_VLDMIA,
|
||||
ARM_INS_VLDR,
|
||||
ARM_INS_VMAXNM,
|
||||
ARM_INS_VMAX,
|
||||
ARM_INS_VMINNM,
|
||||
ARM_INS_VMIN,
|
||||
ARM_INS_VMLA,
|
||||
ARM_INS_VMLAL,
|
||||
ARM_INS_VMLS,
|
||||
ARM_INS_VMLSL,
|
||||
ARM_INS_VMOVL,
|
||||
ARM_INS_VMOVN,
|
||||
ARM_INS_VMSR,
|
||||
ARM_INS_VMUL,
|
||||
ARM_INS_VMULL,
|
||||
ARM_INS_VMVN,
|
||||
ARM_INS_VNEG,
|
||||
ARM_INS_VNMLA,
|
||||
ARM_INS_VNMLS,
|
||||
ARM_INS_VNMUL,
|
||||
ARM_INS_VORN,
|
||||
ARM_INS_VORR,
|
||||
ARM_INS_VPADAL,
|
||||
ARM_INS_VPADDL,
|
||||
ARM_INS_VPADD,
|
||||
ARM_INS_VPMAX,
|
||||
ARM_INS_VPMIN,
|
||||
ARM_INS_VQABS,
|
||||
ARM_INS_VQADD,
|
||||
ARM_INS_VQDMLAL,
|
||||
ARM_INS_VQDMLSL,
|
||||
ARM_INS_VQDMULH,
|
||||
ARM_INS_VQDMULL,
|
||||
ARM_INS_VQMOVUN,
|
||||
ARM_INS_VQMOVN,
|
||||
ARM_INS_VQNEG,
|
||||
ARM_INS_VQRDMULH,
|
||||
ARM_INS_VQRSHL,
|
||||
ARM_INS_VQRSHRN,
|
||||
ARM_INS_VQRSHRUN,
|
||||
ARM_INS_VQSHL,
|
||||
ARM_INS_VQSHLU,
|
||||
ARM_INS_VQSHRN,
|
||||
ARM_INS_VQSHRUN,
|
||||
ARM_INS_VQSUB,
|
||||
ARM_INS_VRADDHN,
|
||||
ARM_INS_VRECPE,
|
||||
ARM_INS_VRECPS,
|
||||
ARM_INS_VREV16,
|
||||
ARM_INS_VREV32,
|
||||
ARM_INS_VREV64,
|
||||
ARM_INS_VRHADD,
|
||||
ARM_INS_VRINTA,
|
||||
ARM_INS_VRINTM,
|
||||
ARM_INS_VRINTN,
|
||||
ARM_INS_VRINTP,
|
||||
ARM_INS_VRINTR,
|
||||
ARM_INS_VRINTX,
|
||||
ARM_INS_VRINTZ,
|
||||
ARM_INS_VRSHL,
|
||||
ARM_INS_VRSHRN,
|
||||
ARM_INS_VRSHR,
|
||||
ARM_INS_VRSQRTE,
|
||||
ARM_INS_VRSQRTS,
|
||||
ARM_INS_VRSRA,
|
||||
ARM_INS_VRSUBHN,
|
||||
ARM_INS_VSELEQ,
|
||||
ARM_INS_VSELGE,
|
||||
ARM_INS_VSELGT,
|
||||
ARM_INS_VSELVS,
|
||||
ARM_INS_VSHLL,
|
||||
ARM_INS_VSHL,
|
||||
ARM_INS_VSHRN,
|
||||
ARM_INS_VSHR,
|
||||
ARM_INS_VSLI,
|
||||
ARM_INS_VSQRT,
|
||||
ARM_INS_VSRA,
|
||||
ARM_INS_VSRI,
|
||||
ARM_INS_VST1,
|
||||
ARM_INS_VST2,
|
||||
ARM_INS_VST3,
|
||||
ARM_INS_VST4,
|
||||
ARM_INS_VSTMDB,
|
||||
ARM_INS_VSTMIA,
|
||||
ARM_INS_VSTR,
|
||||
ARM_INS_VSUB,
|
||||
ARM_INS_VSUBHN,
|
||||
ARM_INS_VSUBL,
|
||||
ARM_INS_VSUBW,
|
||||
ARM_INS_VSWP,
|
||||
ARM_INS_VTBL,
|
||||
ARM_INS_VTBX,
|
||||
ARM_INS_VCVTR,
|
||||
ARM_INS_VTRN,
|
||||
ARM_INS_VTST,
|
||||
ARM_INS_VUZP,
|
||||
ARM_INS_VZIP,
|
||||
ARM_INS_ADDW,
|
||||
ARM_INS_ASR,
|
||||
ARM_INS_DCPS1,
|
||||
ARM_INS_DCPS2,
|
||||
ARM_INS_DCPS3,
|
||||
ARM_INS_IT,
|
||||
ARM_INS_LSL,
|
||||
ARM_INS_LSR,
|
||||
ARM_INS_ORN,
|
||||
ARM_INS_ROR,
|
||||
ARM_INS_RRX,
|
||||
ARM_INS_SUBW,
|
||||
ARM_INS_TBB,
|
||||
ARM_INS_TBH,
|
||||
ARM_INS_CBNZ,
|
||||
ARM_INS_CBZ,
|
||||
ARM_INS_POP,
|
||||
ARM_INS_PUSH,
|
||||
|
||||
// special instructions
|
||||
ARM_INS_NOP,
|
||||
ARM_INS_YIELD,
|
||||
ARM_INS_WFE,
|
||||
ARM_INS_WFI,
|
||||
ARM_INS_SEV,
|
||||
ARM_INS_SEVL,
|
||||
ARM_INS_VPUSH,
|
||||
ARM_INS_VPOP,
|
||||
|
||||
ARM_INS_ENDING, // <-- mark the end of the list of instructions
|
||||
} arm_insn;
|
||||
|
||||
/// Group of ARM instructions
|
||||
typedef enum arm_insn_group {
|
||||
ARM_GRP_INVALID = 0, ///< = CS_GRP_INVALID
|
||||
|
||||
// Generic groups
|
||||
// all jump instructions (conditional+direct+indirect jumps)
|
||||
ARM_GRP_JUMP, ///< = CS_GRP_JUMP
|
||||
ARM_GRP_CALL, ///< = CS_GRP_CALL
|
||||
ARM_GRP_INT = 4, ///< = CS_GRP_INT
|
||||
ARM_GRP_PRIVILEGE = 6, ///< = CS_GRP_PRIVILEGE
|
||||
ARM_GRP_BRANCH_RELATIVE, ///< = CS_GRP_BRANCH_RELATIVE
|
||||
|
||||
// Architecture-specific groups
|
||||
ARM_GRP_CRYPTO = 128,
|
||||
ARM_GRP_DATABARRIER,
|
||||
ARM_GRP_DIVIDE,
|
||||
ARM_GRP_FPARMV8,
|
||||
ARM_GRP_MULTPRO,
|
||||
ARM_GRP_NEON,
|
||||
ARM_GRP_T2EXTRACTPACK,
|
||||
ARM_GRP_THUMB2DSP,
|
||||
ARM_GRP_TRUSTZONE,
|
||||
ARM_GRP_V4T,
|
||||
ARM_GRP_V5T,
|
||||
ARM_GRP_V5TE,
|
||||
ARM_GRP_V6,
|
||||
ARM_GRP_V6T2,
|
||||
ARM_GRP_V7,
|
||||
ARM_GRP_V8,
|
||||
ARM_GRP_VFP2,
|
||||
ARM_GRP_VFP3,
|
||||
ARM_GRP_VFP4,
|
||||
ARM_GRP_ARM,
|
||||
ARM_GRP_MCLASS,
|
||||
ARM_GRP_NOTMCLASS,
|
||||
ARM_GRP_THUMB,
|
||||
ARM_GRP_THUMB1ONLY,
|
||||
ARM_GRP_THUMB2,
|
||||
ARM_GRP_PREV8,
|
||||
ARM_GRP_FPVMLX,
|
||||
ARM_GRP_MULOPS,
|
||||
ARM_GRP_CRC,
|
||||
ARM_GRP_DPVFP,
|
||||
ARM_GRP_V6M,
|
||||
ARM_GRP_VIRTUALIZATION,
|
||||
|
||||
ARM_GRP_ENDING,
|
||||
} arm_insn_group;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,766 @@
|
||||
#ifndef CAPSTONE_ENGINE_H
|
||||
#define CAPSTONE_ENGINE_H
|
||||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2016 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#if defined(CAPSTONE_HAS_OSXKERNEL)
|
||||
#include <libkern/libkern.h>
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#pragma warning(disable:4100)
|
||||
#define CAPSTONE_API __cdecl
|
||||
#ifdef CAPSTONE_SHARED
|
||||
#define CAPSTONE_EXPORT __declspec(dllexport)
|
||||
#else // defined(CAPSTONE_STATIC)
|
||||
#define CAPSTONE_EXPORT
|
||||
#endif
|
||||
#else
|
||||
#define CAPSTONE_API
|
||||
#if defined(__GNUC__) && !defined(CAPSTONE_STATIC)
|
||||
#define CAPSTONE_EXPORT __attribute__((visibility("default")))
|
||||
#else // defined(CAPSTONE_STATIC)
|
||||
#define CAPSTONE_EXPORT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define CAPSTONE_DEPRECATED __attribute__((deprecated))
|
||||
#elif defined(_MSC_VER)
|
||||
#define CAPSTONE_DEPRECATED __declspec(deprecated)
|
||||
#else
|
||||
#pragma message("WARNING: You need to implement CAPSTONE_DEPRECATED for this compiler")
|
||||
#define CAPSTONE_DEPRECATED
|
||||
#endif
|
||||
|
||||
// Capstone API version
|
||||
#define CS_API_MAJOR 4
|
||||
#define CS_API_MINOR 0
|
||||
|
||||
// Version for bleeding edge code of the Github's "next" branch.
|
||||
// Use this if you want the absolutely latest development code.
|
||||
// This version number will be bumped up whenever we have a new major change.
|
||||
#define CS_NEXT_VERSION 5
|
||||
|
||||
// Capstone package version
|
||||
#define CS_VERSION_MAJOR CS_API_MAJOR
|
||||
#define CS_VERSION_MINOR CS_API_MINOR
|
||||
#define CS_VERSION_EXTRA 1
|
||||
|
||||
/// Macro to create combined version which can be compared to
|
||||
/// result of cs_version() API.
|
||||
#define CS_MAKE_VERSION(major, minor) ((major << 8) + minor)
|
||||
|
||||
/// Maximum size of an instruction mnemonic string.
|
||||
#define CS_MNEMONIC_SIZE 32
|
||||
|
||||
// Handle using with all API
|
||||
typedef size_t csh;
|
||||
|
||||
/// Architecture type
|
||||
typedef enum cs_arch {
|
||||
CS_ARCH_ARM = 0, ///< ARM architecture (including Thumb, Thumb-2)
|
||||
CS_ARCH_ARM64, ///< ARM-64, also called AArch64
|
||||
CS_ARCH_MIPS, ///< Mips architecture
|
||||
CS_ARCH_X86, ///< X86 architecture (including x86 & x86-64)
|
||||
CS_ARCH_PPC, ///< PowerPC architecture
|
||||
CS_ARCH_SPARC, ///< Sparc architecture
|
||||
CS_ARCH_SYSZ, ///< SystemZ architecture
|
||||
CS_ARCH_XCORE, ///< XCore architecture
|
||||
CS_ARCH_M68K, ///< 68K architecture
|
||||
CS_ARCH_TMS320C64X, ///< TMS320C64x architecture
|
||||
CS_ARCH_M680X, ///< 680X architecture
|
||||
CS_ARCH_EVM, ///< Ethereum architecture
|
||||
CS_ARCH_MAX,
|
||||
CS_ARCH_ALL = 0xFFFF, // All architectures - for cs_support()
|
||||
} cs_arch;
|
||||
|
||||
// Support value to verify diet mode of the engine.
|
||||
// If cs_support(CS_SUPPORT_DIET) return True, the engine was compiled
|
||||
// in diet mode.
|
||||
#define CS_SUPPORT_DIET (CS_ARCH_ALL + 1)
|
||||
|
||||
// Support value to verify X86 reduce mode of the engine.
|
||||
// If cs_support(CS_SUPPORT_X86_REDUCE) return True, the engine was compiled
|
||||
// in X86 reduce mode.
|
||||
#define CS_SUPPORT_X86_REDUCE (CS_ARCH_ALL + 2)
|
||||
|
||||
/// Mode type
|
||||
typedef enum cs_mode {
|
||||
CS_MODE_LITTLE_ENDIAN = 0, ///< little-endian mode (default mode)
|
||||
CS_MODE_ARM = 0, ///< 32-bit ARM
|
||||
CS_MODE_16 = 1 << 1, ///< 16-bit mode (X86)
|
||||
CS_MODE_32 = 1 << 2, ///< 32-bit mode (X86)
|
||||
CS_MODE_64 = 1 << 3, ///< 64-bit mode (X86, PPC)
|
||||
CS_MODE_THUMB = 1 << 4, ///< ARM's Thumb mode, including Thumb-2
|
||||
CS_MODE_MCLASS = 1 << 5, ///< ARM's Cortex-M series
|
||||
CS_MODE_V8 = 1 << 6, ///< ARMv8 A32 encodings for ARM
|
||||
CS_MODE_MICRO = 1 << 4, ///< MicroMips mode (MIPS)
|
||||
CS_MODE_MIPS3 = 1 << 5, ///< Mips III ISA
|
||||
CS_MODE_MIPS32R6 = 1 << 6, ///< Mips32r6 ISA
|
||||
CS_MODE_MIPS2 = 1 << 7, ///< Mips II ISA
|
||||
CS_MODE_V9 = 1 << 4, ///< SparcV9 mode (Sparc)
|
||||
CS_MODE_QPX = 1 << 4, ///< Quad Processing eXtensions mode (PPC)
|
||||
CS_MODE_M68K_000 = 1 << 1, ///< M68K 68000 mode
|
||||
CS_MODE_M68K_010 = 1 << 2, ///< M68K 68010 mode
|
||||
CS_MODE_M68K_020 = 1 << 3, ///< M68K 68020 mode
|
||||
CS_MODE_M68K_030 = 1 << 4, ///< M68K 68030 mode
|
||||
CS_MODE_M68K_040 = 1 << 5, ///< M68K 68040 mode
|
||||
CS_MODE_M68K_060 = 1 << 6, ///< M68K 68060 mode
|
||||
CS_MODE_BIG_ENDIAN = 1 << 31, ///< big-endian mode
|
||||
CS_MODE_MIPS32 = CS_MODE_32, ///< Mips32 ISA (Mips)
|
||||
CS_MODE_MIPS64 = CS_MODE_64, ///< Mips64 ISA (Mips)
|
||||
CS_MODE_M680X_6301 = 1 << 1, ///< M680X Hitachi 6301,6303 mode
|
||||
CS_MODE_M680X_6309 = 1 << 2, ///< M680X Hitachi 6309 mode
|
||||
CS_MODE_M680X_6800 = 1 << 3, ///< M680X Motorola 6800,6802 mode
|
||||
CS_MODE_M680X_6801 = 1 << 4, ///< M680X Motorola 6801,6803 mode
|
||||
CS_MODE_M680X_6805 = 1 << 5, ///< M680X Motorola/Freescale 6805 mode
|
||||
CS_MODE_M680X_6808 = 1 << 6, ///< M680X Motorola/Freescale/NXP 68HC08 mode
|
||||
CS_MODE_M680X_6809 = 1 << 7, ///< M680X Motorola 6809 mode
|
||||
CS_MODE_M680X_6811 = 1 << 8, ///< M680X Motorola/Freescale/NXP 68HC11 mode
|
||||
CS_MODE_M680X_CPU12 = 1 << 9, ///< M680X Motorola/Freescale/NXP CPU12
|
||||
///< used on M68HC12/HCS12
|
||||
CS_MODE_M680X_HCS08 = 1 << 10, ///< M680X Freescale/NXP HCS08 mode
|
||||
} cs_mode;
|
||||
|
||||
typedef void* (CAPSTONE_API *cs_malloc_t)(size_t size);
|
||||
typedef void* (CAPSTONE_API *cs_calloc_t)(size_t nmemb, size_t size);
|
||||
typedef void* (CAPSTONE_API *cs_realloc_t)(void *ptr, size_t size);
|
||||
typedef void (CAPSTONE_API *cs_free_t)(void *ptr);
|
||||
typedef int (CAPSTONE_API *cs_vsnprintf_t)(char *str, size_t size, const char *format, va_list ap);
|
||||
|
||||
|
||||
/// User-defined dynamic memory related functions: malloc/calloc/realloc/free/vsnprintf()
|
||||
/// By default, Capstone uses system's malloc(), calloc(), realloc(), free() & vsnprintf().
|
||||
typedef struct cs_opt_mem {
|
||||
cs_malloc_t malloc;
|
||||
cs_calloc_t calloc;
|
||||
cs_realloc_t realloc;
|
||||
cs_free_t free;
|
||||
cs_vsnprintf_t vsnprintf;
|
||||
} cs_opt_mem;
|
||||
|
||||
/// Customize mnemonic for instructions with alternative name.
|
||||
/// To reset existing customized instruction to its default mnemonic,
|
||||
/// call cs_option(CS_OPT_MNEMONIC) again with the same @id and NULL value
|
||||
/// for @mnemonic.
|
||||
typedef struct cs_opt_mnem {
|
||||
/// ID of instruction to be customized.
|
||||
unsigned int id;
|
||||
/// Customized instruction mnemonic.
|
||||
const char *mnemonic;
|
||||
} cs_opt_mnem;
|
||||
|
||||
/// Runtime option for the disassembled engine
|
||||
typedef enum cs_opt_type {
|
||||
CS_OPT_INVALID = 0, ///< No option specified
|
||||
CS_OPT_SYNTAX, ///< Assembly output syntax
|
||||
CS_OPT_DETAIL, ///< Break down instruction structure into details
|
||||
CS_OPT_MODE, ///< Change engine's mode at run-time
|
||||
CS_OPT_MEM, ///< User-defined dynamic memory related functions
|
||||
CS_OPT_SKIPDATA, ///< Skip data when disassembling. Then engine is in SKIPDATA mode.
|
||||
CS_OPT_SKIPDATA_SETUP, ///< Setup user-defined function for SKIPDATA option
|
||||
CS_OPT_MNEMONIC, ///< Customize instruction mnemonic
|
||||
CS_OPT_UNSIGNED, ///< print immediate operands in unsigned form
|
||||
} cs_opt_type;
|
||||
|
||||
/// Runtime option value (associated with option type above)
|
||||
typedef enum cs_opt_value {
|
||||
CS_OPT_OFF = 0, ///< Turn OFF an option - default for CS_OPT_DETAIL, CS_OPT_SKIPDATA, CS_OPT_UNSIGNED.
|
||||
CS_OPT_ON = 3, ///< Turn ON an option (CS_OPT_DETAIL, CS_OPT_SKIPDATA).
|
||||
CS_OPT_SYNTAX_DEFAULT = 0, ///< Default asm syntax (CS_OPT_SYNTAX).
|
||||
CS_OPT_SYNTAX_INTEL, ///< X86 Intel asm syntax - default on X86 (CS_OPT_SYNTAX).
|
||||
CS_OPT_SYNTAX_ATT, ///< X86 ATT asm syntax (CS_OPT_SYNTAX).
|
||||
CS_OPT_SYNTAX_NOREGNAME, ///< Prints register name with only number (CS_OPT_SYNTAX)
|
||||
CS_OPT_SYNTAX_MASM, ///< X86 Intel Masm syntax (CS_OPT_SYNTAX).
|
||||
} cs_opt_value;
|
||||
|
||||
/// Common instruction operand types - to be consistent across all architectures.
|
||||
typedef enum cs_op_type {
|
||||
CS_OP_INVALID = 0, ///< uninitialized/invalid operand.
|
||||
CS_OP_REG, ///< Register operand.
|
||||
CS_OP_IMM, ///< Immediate operand.
|
||||
CS_OP_MEM, ///< Memory operand.
|
||||
CS_OP_FP, ///< Floating-Point operand.
|
||||
} cs_op_type;
|
||||
|
||||
/// 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
|
||||
typedef enum cs_ac_type {
|
||||
CS_AC_INVALID = 0, ///< Uninitialized/invalid access type.
|
||||
CS_AC_READ = 1 << 0, ///< Operand read from memory or register.
|
||||
CS_AC_WRITE = 1 << 1, ///< Operand write to memory or register.
|
||||
} cs_ac_type;
|
||||
|
||||
/// Common instruction groups - to be consistent across all architectures.
|
||||
typedef enum cs_group_type {
|
||||
CS_GRP_INVALID = 0, ///< uninitialized/invalid group.
|
||||
CS_GRP_JUMP, ///< all jump instructions (conditional+direct+indirect jumps)
|
||||
CS_GRP_CALL, ///< all call instructions
|
||||
CS_GRP_RET, ///< all return instructions
|
||||
CS_GRP_INT, ///< all interrupt instructions (int+syscall)
|
||||
CS_GRP_IRET, ///< all interrupt return instructions
|
||||
CS_GRP_PRIVILEGE, ///< all privileged instructions
|
||||
CS_GRP_BRANCH_RELATIVE, ///< all relative branching instructions
|
||||
} cs_group_type;
|
||||
|
||||
/**
|
||||
User-defined callback function for SKIPDATA option.
|
||||
See tests/test_skipdata.c for sample code demonstrating this API.
|
||||
|
||||
@code: the input buffer containing code to be disassembled.
|
||||
This is the same buffer passed to cs_disasm().
|
||||
@code_size: size (in bytes) of the above @code buffer.
|
||||
@offset: the position of the currently-examining byte in the input
|
||||
buffer @code mentioned above.
|
||||
@user_data: user-data passed to cs_option() via @user_data field in
|
||||
cs_opt_skipdata struct below.
|
||||
|
||||
@return: return number of bytes to skip, or 0 to immediately stop disassembling.
|
||||
*/
|
||||
typedef size_t (CAPSTONE_API *cs_skipdata_cb_t)(const uint8_t *code, size_t code_size, size_t offset, void *user_data);
|
||||
|
||||
/// User-customized setup for SKIPDATA option
|
||||
typedef struct cs_opt_skipdata {
|
||||
/// Capstone considers data to skip as special "instructions".
|
||||
/// User can specify the string for this instruction's "mnemonic" here.
|
||||
/// By default (if @mnemonic is NULL), Capstone use ".byte".
|
||||
const char *mnemonic;
|
||||
|
||||
/// User-defined callback function to be called when Capstone hits data.
|
||||
/// If the returned value from this callback is positive (>0), Capstone
|
||||
/// will skip exactly that number of bytes & continue. Otherwise, if
|
||||
/// the callback returns 0, Capstone stops disassembling and returns
|
||||
/// immediately from cs_disasm()
|
||||
/// NOTE: if this callback pointer is NULL, Capstone would skip a number
|
||||
/// of bytes depending on architectures, as following:
|
||||
/// Arm: 2 bytes (Thumb mode) or 4 bytes.
|
||||
/// Arm64: 4 bytes.
|
||||
/// Mips: 4 bytes.
|
||||
/// M680x: 1 byte.
|
||||
/// PowerPC: 4 bytes.
|
||||
/// Sparc: 4 bytes.
|
||||
/// SystemZ: 2 bytes.
|
||||
/// X86: 1 bytes.
|
||||
/// XCore: 2 bytes.
|
||||
/// EVM: 1 bytes.
|
||||
cs_skipdata_cb_t callback; // default value is NULL
|
||||
|
||||
/// User-defined data to be passed to @callback function pointer.
|
||||
void *user_data;
|
||||
} cs_opt_skipdata;
|
||||
|
||||
|
||||
#include "arm.h"
|
||||
#include "arm64.h"
|
||||
#include "m68k.h"
|
||||
#include "mips.h"
|
||||
#include "ppc.h"
|
||||
#include "sparc.h"
|
||||
#include "systemz.h"
|
||||
#include "x86.h"
|
||||
#include "xcore.h"
|
||||
#include "tms320c64x.h"
|
||||
#include "m680x.h"
|
||||
#include "evm.h"
|
||||
|
||||
/// NOTE: All information in cs_detail is only available when CS_OPT_DETAIL = CS_OPT_ON
|
||||
/// Initialized as memset(., 0, offsetof(cs_detail, ARCH)+sizeof(cs_ARCH))
|
||||
/// by ARCH_getInstruction in arch/ARCH/ARCHDisassembler.c
|
||||
/// if cs_detail changes, in particular if a field is added after the union,
|
||||
/// then update arch/ARCH/ARCHDisassembler.c accordingly
|
||||
typedef struct cs_detail {
|
||||
uint16_t regs_read[12]; ///< list of implicit registers read by this insn
|
||||
uint8_t regs_read_count; ///< number of implicit registers read by this insn
|
||||
|
||||
uint16_t regs_write[20]; ///< list of implicit registers modified by this insn
|
||||
uint8_t regs_write_count; ///< number of implicit registers modified by this insn
|
||||
|
||||
uint8_t groups[8]; ///< list of group this instruction belong to
|
||||
uint8_t groups_count; ///< number of groups this insn belongs to
|
||||
|
||||
/// Architecture-specific instruction info
|
||||
union {
|
||||
cs_x86 x86; ///< X86 architecture, including 16-bit, 32-bit & 64-bit mode
|
||||
cs_arm64 arm64; ///< ARM64 architecture (aka AArch64)
|
||||
cs_arm arm; ///< ARM architecture (including Thumb/Thumb2)
|
||||
cs_m68k m68k; ///< M68K architecture
|
||||
cs_mips mips; ///< MIPS architecture
|
||||
cs_ppc ppc; ///< PowerPC architecture
|
||||
cs_sparc sparc; ///< Sparc architecture
|
||||
cs_sysz sysz; ///< SystemZ architecture
|
||||
cs_xcore xcore; ///< XCore architecture
|
||||
cs_tms320c64x tms320c64x; ///< TMS320C64x architecture
|
||||
cs_m680x m680x; ///< M680X architecture
|
||||
cs_evm evm; ///< Ethereum architecture
|
||||
};
|
||||
} cs_detail;
|
||||
|
||||
/// Detail information of disassembled instruction
|
||||
typedef struct cs_insn {
|
||||
/// 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.
|
||||
unsigned int id;
|
||||
|
||||
/// Address (EIP) of this instruction
|
||||
/// This information is available even when CS_OPT_DETAIL = CS_OPT_OFF
|
||||
uint64_t address;
|
||||
|
||||
/// Size of this instruction
|
||||
/// This information is available even when CS_OPT_DETAIL = CS_OPT_OFF
|
||||
uint16_t size;
|
||||
|
||||
/// 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
|
||||
uint8_t bytes[16];
|
||||
|
||||
/// Ascii text of instruction mnemonic
|
||||
/// This information is available even when CS_OPT_DETAIL = CS_OPT_OFF
|
||||
char mnemonic[CS_MNEMONIC_SIZE];
|
||||
|
||||
/// Ascii text of instruction operands
|
||||
/// This information is available even when CS_OPT_DETAIL = CS_OPT_OFF
|
||||
char op_str[160];
|
||||
|
||||
/// Pointer to cs_detail.
|
||||
/// NOTE: detail pointer 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)
|
||||
///
|
||||
/// NOTE 2: when in Skipdata mode, or when detail mode is OFF, even if this pointer
|
||||
/// is not NULL, its content is still irrelevant.
|
||||
cs_detail *detail;
|
||||
} cs_insn;
|
||||
|
||||
|
||||
/// Calculate the offset of a disassembled instruction in its buffer, given its position
|
||||
/// in its array of disassembled insn
|
||||
/// NOTE: this macro works with position (>=1), not index
|
||||
#define CS_INSN_OFFSET(insns, post) (insns[post - 1].address - insns[0].address)
|
||||
|
||||
|
||||
/// All type of errors encountered by Capstone API.
|
||||
/// These are values returned by cs_errno()
|
||||
typedef enum cs_err {
|
||||
CS_ERR_OK = 0, ///< No error: everything was fine
|
||||
CS_ERR_MEM, ///< Out-Of-Memory error: cs_open(), cs_disasm(), cs_disasm_iter()
|
||||
CS_ERR_ARCH, ///< Unsupported architecture: cs_open()
|
||||
CS_ERR_HANDLE, ///< Invalid handle: cs_op_count(), cs_op_index()
|
||||
CS_ERR_CSH, ///< Invalid csh argument: cs_close(), cs_errno(), cs_option()
|
||||
CS_ERR_MODE, ///< Invalid/unsupported mode: cs_open()
|
||||
CS_ERR_OPTION, ///< Invalid/unsupported option: cs_option()
|
||||
CS_ERR_DETAIL, ///< Information is unavailable because detail option is OFF
|
||||
CS_ERR_MEMSETUP, ///< Dynamic memory management uninitialized (see CS_OPT_MEM)
|
||||
CS_ERR_VERSION, ///< Unsupported version (bindings)
|
||||
CS_ERR_DIET, ///< Access irrelevant data in "diet" engine
|
||||
CS_ERR_SKIPDATA, ///< Access irrelevant data for "data" instruction in SKIPDATA mode
|
||||
CS_ERR_X86_ATT, ///< X86 AT&T syntax is unsupported (opt-out at compile time)
|
||||
CS_ERR_X86_INTEL, ///< X86 Intel syntax is unsupported (opt-out at compile time)
|
||||
CS_ERR_X86_MASM, ///< X86 Intel syntax is unsupported (opt-out at compile time)
|
||||
} cs_err;
|
||||
|
||||
/**
|
||||
Return combined API version & major and minor version numbers.
|
||||
|
||||
@major: major number of API version
|
||||
@minor: minor number of API version
|
||||
|
||||
@return hexical number as (major << 8 | minor), which encodes both
|
||||
major & minor versions.
|
||||
NOTE: This returned value can be compared with version number made
|
||||
with macro CS_MAKE_VERSION
|
||||
|
||||
For example, second API version would return 1 in @major, and 1 in @minor
|
||||
The return value would be 0x0101
|
||||
|
||||
NOTE: if you only care about returned value, but not major and minor values,
|
||||
set both @major & @minor arguments to NULL.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
unsigned int CAPSTONE_API cs_version(int *major, int *minor);
|
||||
|
||||
|
||||
/**
|
||||
This API can be used to either ask for archs supported by this library,
|
||||
or check to see if the library was compile with 'diet' option (or called
|
||||
in 'diet' mode).
|
||||
|
||||
To check if a particular arch is supported by this library, set @query to
|
||||
arch mode (CS_ARCH_* value).
|
||||
To verify if this library supports all the archs, use CS_ARCH_ALL.
|
||||
|
||||
To check if this library is in 'diet' mode, set @query to CS_SUPPORT_DIET.
|
||||
|
||||
@return True if this library supports the given arch, or in 'diet' mode.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
bool CAPSTONE_API cs_support(int query);
|
||||
|
||||
/**
|
||||
Initialize CS handle: this must be done before any usage of CS.
|
||||
|
||||
@arch: architecture type (CS_ARCH_*)
|
||||
@mode: hardware mode. This is combined of CS_MODE_*
|
||||
@handle: pointer to handle, which will be updated at return time
|
||||
|
||||
@return CS_ERR_OK on success, or other value on failure (refer to cs_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
cs_err CAPSTONE_API cs_open(cs_arch arch, cs_mode mode, csh *handle);
|
||||
|
||||
/**
|
||||
Close CS handle: MUST do to release the handle when it is not used anymore.
|
||||
NOTE: this must be only called when there is no longer usage of Capstone,
|
||||
not even access to cs_insn array. The reason is the this API releases some
|
||||
cached memory, thus access to any Capstone API after cs_close() might crash
|
||||
your application.
|
||||
|
||||
In fact,this API invalidate @handle by ZERO out its value (i.e *handle = 0).
|
||||
|
||||
@handle: pointer to a handle returned by cs_open()
|
||||
|
||||
@return CS_ERR_OK on success, or other value on failure (refer to cs_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
cs_err CAPSTONE_API cs_close(csh *handle);
|
||||
|
||||
/**
|
||||
Set option for disassembling engine at runtime
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
@type: type of option to be set
|
||||
@value: option value corresponding with @type
|
||||
|
||||
@return: CS_ERR_OK on success, or other value on failure.
|
||||
Refer to cs_err enum for detailed error.
|
||||
|
||||
NOTE: in the case of CS_OPT_MEM, handle's value can be anything,
|
||||
so that cs_option(handle, CS_OPT_MEM, value) can (i.e must) be called
|
||||
even before cs_open()
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
cs_err CAPSTONE_API cs_option(csh handle, cs_opt_type type, size_t value);
|
||||
|
||||
/**
|
||||
Report the last error number when some API function fail.
|
||||
Like glibc's errno, cs_errno might not retain its old value once accessed.
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
|
||||
@return: error code of cs_err enum type (CS_ERR_*, see above)
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
cs_err CAPSTONE_API cs_errno(csh handle);
|
||||
|
||||
|
||||
/**
|
||||
Return a string describing given error code.
|
||||
|
||||
@code: error code (see CS_ERR_* above)
|
||||
|
||||
@return: returns a pointer to a string that describes the error code
|
||||
passed in the argument @code
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
const char * CAPSTONE_API cs_strerror(cs_err code);
|
||||
|
||||
/**
|
||||
Disassemble binary code, given the code buffer, size, address and number
|
||||
of instructions to be decoded.
|
||||
This API dynamically allocate memory to contain disassembled instruction.
|
||||
Resulting instructions will be put into @*insn
|
||||
|
||||
NOTE 1: this API will automatically determine memory needed to contain
|
||||
output disassembled instructions in @insn.
|
||||
|
||||
NOTE 2: caller must free the allocated memory itself to avoid memory leaking.
|
||||
|
||||
NOTE 3: for system with scarce memory to be dynamically allocated such as
|
||||
OS kernel or firmware, the API cs_disasm_iter() might be a better choice than
|
||||
cs_disasm(). The reason is that with cs_disasm(), based on limited available
|
||||
memory, we have to calculate in advance how many instructions to be disassembled,
|
||||
which complicates things. This is especially troublesome for the case @count=0,
|
||||
when cs_disasm() runs uncontrollably (until either end of input buffer, or
|
||||
when it encounters an invalid instruction).
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
@code: buffer containing raw binary code to be disassembled.
|
||||
@code_size: size of the above code buffer.
|
||||
@address: address of the first instruction in given raw code buffer.
|
||||
@insn: array of instructions filled in by this API.
|
||||
NOTE: @insn will be allocated by this function, and should be freed
|
||||
with cs_free() API.
|
||||
@count: number of instructions to be disassembled, or 0 to get all of them
|
||||
|
||||
@return: the number of successfully disassembled instructions,
|
||||
or 0 if this function failed to disassemble the given code
|
||||
|
||||
On failure, call cs_errno() for error code.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
size_t CAPSTONE_API cs_disasm(csh handle,
|
||||
const uint8_t *code, size_t code_size,
|
||||
uint64_t address,
|
||||
size_t count,
|
||||
cs_insn **insn);
|
||||
|
||||
/**
|
||||
Deprecated function - to be retired in the next version!
|
||||
Use cs_disasm() instead of cs_disasm_ex()
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
CAPSTONE_DEPRECATED
|
||||
size_t CAPSTONE_API cs_disasm_ex(csh handle,
|
||||
const uint8_t *code, size_t code_size,
|
||||
uint64_t address,
|
||||
size_t count,
|
||||
cs_insn **insn);
|
||||
|
||||
/**
|
||||
Free memory allocated by cs_malloc() or cs_disasm() (argument @insn)
|
||||
|
||||
@insn: pointer returned by @insn argument in cs_disasm() or cs_malloc()
|
||||
@count: number of cs_insn structures returned by cs_disasm(), or 1
|
||||
to free memory allocated by cs_malloc().
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
void CAPSTONE_API cs_free(cs_insn *insn, size_t count);
|
||||
|
||||
|
||||
/**
|
||||
Allocate memory for 1 instruction to be used by cs_disasm_iter().
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
|
||||
NOTE: when no longer in use, you can reclaim the memory allocated for
|
||||
this instruction with cs_free(insn, 1)
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
cs_insn * CAPSTONE_API cs_malloc(csh handle);
|
||||
|
||||
/**
|
||||
Fast API to disassemble binary code, given the code buffer, size, address
|
||||
and number of instructions to be decoded.
|
||||
This API puts the resulting instruction into a given cache in @insn.
|
||||
See tests/test_iter.c for sample code demonstrating this API.
|
||||
|
||||
NOTE 1: this API will update @code, @size & @address to point to the next
|
||||
instruction in the input buffer. Therefore, it is convenient to use
|
||||
cs_disasm_iter() inside a loop to quickly iterate all the instructions.
|
||||
While decoding one instruction at a time can also be achieved with
|
||||
cs_disasm(count=1), some benchmarks shown that cs_disasm_iter() can be 30%
|
||||
faster on random input.
|
||||
|
||||
NOTE 2: the cache in @insn can be created with cs_malloc() API.
|
||||
|
||||
NOTE 3: for system with scarce memory to be dynamically allocated such as
|
||||
OS kernel or firmware, this API is recommended over cs_disasm(), which
|
||||
allocates memory based on the number of instructions to be disassembled.
|
||||
The reason is that with cs_disasm(), based on limited available memory,
|
||||
we have to calculate in advance how many instructions to be disassembled,
|
||||
which complicates things. This is especially troublesome for the case
|
||||
@count=0, when cs_disasm() runs uncontrollably (until either end of input
|
||||
buffer, or when it encounters an invalid instruction).
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
@code: buffer containing raw binary code to be disassembled
|
||||
@size: size of above code
|
||||
@address: address of the first insn in given raw code buffer
|
||||
@insn: pointer to instruction to be filled in by this API.
|
||||
|
||||
@return: true if this API successfully decode 1 instruction,
|
||||
or false otherwise.
|
||||
|
||||
On failure, call cs_errno() for error code.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
bool CAPSTONE_API cs_disasm_iter(csh handle,
|
||||
const uint8_t **code, size_t *size,
|
||||
uint64_t *address, cs_insn *insn);
|
||||
|
||||
/**
|
||||
Return friendly name of register in a string.
|
||||
Find the instruction id from header file of corresponding architecture (arm.h for ARM,
|
||||
x86.h for X86, ...)
|
||||
|
||||
WARN: when in 'diet' mode, this API is irrelevant because engine does not
|
||||
store register name.
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
@reg_id: register id
|
||||
|
||||
@return: string name of the register, or NULL if @reg_id is invalid.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
const char * CAPSTONE_API cs_reg_name(csh handle, unsigned int reg_id);
|
||||
|
||||
/**
|
||||
Return friendly name of an instruction in a string.
|
||||
Find the instruction id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...)
|
||||
|
||||
WARN: when in 'diet' mode, this API is irrelevant because the engine does not
|
||||
store instruction name.
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
@insn_id: instruction id
|
||||
|
||||
@return: string name of the instruction, or NULL if @insn_id is invalid.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
const char * CAPSTONE_API cs_insn_name(csh handle, unsigned int insn_id);
|
||||
|
||||
/**
|
||||
Return friendly name of a group id (that an instruction can belong to)
|
||||
Find the group id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...)
|
||||
|
||||
WARN: when in 'diet' mode, this API is irrelevant because the engine does not
|
||||
store group name.
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
@group_id: group id
|
||||
|
||||
@return: string name of the group, or NULL if @group_id is invalid.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
const char * CAPSTONE_API cs_group_name(csh handle, unsigned int group_id);
|
||||
|
||||
/**
|
||||
Check if a disassembled instruction belong to a particular group.
|
||||
Find the group id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...)
|
||||
Internally, this simply verifies if @group_id matches any member of insn->groups array.
|
||||
|
||||
NOTE: this API is only valid when detail option is ON (which is OFF by default).
|
||||
|
||||
WARN: when in 'diet' mode, this API is irrelevant because the engine does not
|
||||
update @groups array.
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
@insn: disassembled instruction structure received from cs_disasm() or cs_disasm_iter()
|
||||
@group_id: group that you want to check if this instruction belong to.
|
||||
|
||||
@return: true if this instruction indeed belongs to the given group, or false otherwise.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
bool CAPSTONE_API cs_insn_group(csh handle, const cs_insn *insn, unsigned int group_id);
|
||||
|
||||
/**
|
||||
Check if a disassembled instruction IMPLICITLY used a particular register.
|
||||
Find the register id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...)
|
||||
Internally, this simply verifies if @reg_id matches any member of insn->regs_read array.
|
||||
|
||||
NOTE: this API is only valid when detail option is ON (which is OFF by default)
|
||||
|
||||
WARN: when in 'diet' mode, this API is irrelevant because the engine does not
|
||||
update @regs_read array.
|
||||
|
||||
@insn: disassembled instruction structure received from cs_disasm() or cs_disasm_iter()
|
||||
@reg_id: register that you want to check if this instruction used it.
|
||||
|
||||
@return: true if this instruction indeed implicitly used the given register, or false otherwise.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
bool CAPSTONE_API cs_reg_read(csh handle, const cs_insn *insn, unsigned int reg_id);
|
||||
|
||||
/**
|
||||
Check if a disassembled instruction IMPLICITLY modified a particular register.
|
||||
Find the register id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...)
|
||||
Internally, this simply verifies if @reg_id matches any member of insn->regs_write array.
|
||||
|
||||
NOTE: this API is only valid when detail option is ON (which is OFF by default)
|
||||
|
||||
WARN: when in 'diet' mode, this API is irrelevant because the engine does not
|
||||
update @regs_write array.
|
||||
|
||||
@insn: disassembled instruction structure received from cs_disasm() or cs_disasm_iter()
|
||||
@reg_id: register that you want to check if this instruction modified it.
|
||||
|
||||
@return: true if this instruction indeed implicitly modified the given register, or false otherwise.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
bool CAPSTONE_API cs_reg_write(csh handle, const cs_insn *insn, unsigned int reg_id);
|
||||
|
||||
/**
|
||||
Count the number of operands of a given type.
|
||||
Find the operand type in header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...)
|
||||
|
||||
NOTE: this API is only valid when detail option is ON (which is OFF by default)
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
@insn: disassembled instruction structure received from cs_disasm() or cs_disasm_iter()
|
||||
@op_type: Operand type to be found.
|
||||
|
||||
@return: number of operands of given type @op_type in instruction @insn,
|
||||
or -1 on failure.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
int CAPSTONE_API cs_op_count(csh handle, const cs_insn *insn, unsigned int op_type);
|
||||
|
||||
/**
|
||||
Retrieve the position of operand of given type in <arch>.operands[] array.
|
||||
Later, the operand can be accessed using the returned position.
|
||||
Find the operand type in header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...)
|
||||
|
||||
NOTE: this API is only valid when detail option is ON (which is OFF by default)
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
@insn: disassembled instruction structure received from cs_disasm() or cs_disasm_iter()
|
||||
@op_type: Operand type to be found.
|
||||
@position: position of the operand to be found. This must be in the range
|
||||
[1, cs_op_count(handle, insn, op_type)]
|
||||
|
||||
@return: index of operand of given type @op_type in <arch>.operands[] array
|
||||
in instruction @insn, or -1 on failure.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
int CAPSTONE_API cs_op_index(csh handle, const cs_insn *insn, unsigned int op_type,
|
||||
unsigned int position);
|
||||
|
||||
/// Type of array to keep the list of registers
|
||||
typedef uint16_t cs_regs[64];
|
||||
|
||||
/**
|
||||
Retrieve all the registers accessed by an instruction, either explicitly or
|
||||
implicitly.
|
||||
|
||||
WARN: when in 'diet' mode, this API is irrelevant because engine does not
|
||||
store registers.
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
@insn: disassembled instruction structure returned from cs_disasm() or cs_disasm_iter()
|
||||
@regs_read: on return, this array contains all registers read by instruction.
|
||||
@regs_read_count: number of registers kept inside @regs_read array.
|
||||
@regs_write: on return, this array contains all registers written by instruction.
|
||||
@regs_write_count: number of registers kept inside @regs_write array.
|
||||
|
||||
@return CS_ERR_OK on success, or other value on failure (refer to cs_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
cs_err CAPSTONE_API cs_regs_access(csh handle, const cs_insn *insn,
|
||||
cs_regs regs_read, uint8_t *regs_read_count,
|
||||
cs_regs regs_write, uint8_t *regs_write_count);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,188 @@
|
||||
#ifndef CAPSTONE_EVM_H
|
||||
#define CAPSTONE_EVM_H
|
||||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2018 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
/// Instruction structure
|
||||
typedef struct cs_evm {
|
||||
unsigned char pop; ///< number of items popped from the stack
|
||||
unsigned char push; ///< number of items pushed into the stack
|
||||
unsigned int fee; ///< gas fee for the instruction
|
||||
} cs_evm;
|
||||
|
||||
/// EVM instruction
|
||||
typedef enum evm_insn {
|
||||
EVM_INS_STOP = 0,
|
||||
EVM_INS_ADD = 1,
|
||||
EVM_INS_MUL = 2,
|
||||
EVM_INS_SUB = 3,
|
||||
EVM_INS_DIV = 4,
|
||||
EVM_INS_SDIV = 5,
|
||||
EVM_INS_MOD = 6,
|
||||
EVM_INS_SMOD = 7,
|
||||
EVM_INS_ADDMOD = 8,
|
||||
EVM_INS_MULMOD = 9,
|
||||
EVM_INS_EXP = 10,
|
||||
EVM_INS_SIGNEXTEND = 11,
|
||||
EVM_INS_LT = 16,
|
||||
EVM_INS_GT = 17,
|
||||
EVM_INS_SLT = 18,
|
||||
EVM_INS_SGT = 19,
|
||||
EVM_INS_EQ = 20,
|
||||
EVM_INS_ISZERO = 21,
|
||||
EVM_INS_AND = 22,
|
||||
EVM_INS_OR = 23,
|
||||
EVM_INS_XOR = 24,
|
||||
EVM_INS_NOT = 25,
|
||||
EVM_INS_BYTE = 26,
|
||||
EVM_INS_SHA3 = 32,
|
||||
EVM_INS_ADDRESS = 48,
|
||||
EVM_INS_BALANCE = 49,
|
||||
EVM_INS_ORIGIN = 50,
|
||||
EVM_INS_CALLER = 51,
|
||||
EVM_INS_CALLVALUE = 52,
|
||||
EVM_INS_CALLDATALOAD = 53,
|
||||
EVM_INS_CALLDATASIZE = 54,
|
||||
EVM_INS_CALLDATACOPY = 55,
|
||||
EVM_INS_CODESIZE = 56,
|
||||
EVM_INS_CODECOPY = 57,
|
||||
EVM_INS_GASPRICE = 58,
|
||||
EVM_INS_EXTCODESIZE = 59,
|
||||
EVM_INS_EXTCODECOPY = 60,
|
||||
EVM_INS_RETURNDATASIZE = 61,
|
||||
EVM_INS_RETURNDATACOPY = 62,
|
||||
EVM_INS_BLOCKHASH = 64,
|
||||
EVM_INS_COINBASE = 65,
|
||||
EVM_INS_TIMESTAMP = 66,
|
||||
EVM_INS_NUMBER = 67,
|
||||
EVM_INS_DIFFICULTY = 68,
|
||||
EVM_INS_GASLIMIT = 69,
|
||||
EVM_INS_POP = 80,
|
||||
EVM_INS_MLOAD = 81,
|
||||
EVM_INS_MSTORE = 82,
|
||||
EVM_INS_MSTORE8 = 83,
|
||||
EVM_INS_SLOAD = 84,
|
||||
EVM_INS_SSTORE = 85,
|
||||
EVM_INS_JUMP = 86,
|
||||
EVM_INS_JUMPI = 87,
|
||||
EVM_INS_PC = 88,
|
||||
EVM_INS_MSIZE = 89,
|
||||
EVM_INS_GAS = 90,
|
||||
EVM_INS_JUMPDEST = 91,
|
||||
EVM_INS_PUSH1 = 96,
|
||||
EVM_INS_PUSH2 = 97,
|
||||
EVM_INS_PUSH3 = 98,
|
||||
EVM_INS_PUSH4 = 99,
|
||||
EVM_INS_PUSH5 = 100,
|
||||
EVM_INS_PUSH6 = 101,
|
||||
EVM_INS_PUSH7 = 102,
|
||||
EVM_INS_PUSH8 = 103,
|
||||
EVM_INS_PUSH9 = 104,
|
||||
EVM_INS_PUSH10 = 105,
|
||||
EVM_INS_PUSH11 = 106,
|
||||
EVM_INS_PUSH12 = 107,
|
||||
EVM_INS_PUSH13 = 108,
|
||||
EVM_INS_PUSH14 = 109,
|
||||
EVM_INS_PUSH15 = 110,
|
||||
EVM_INS_PUSH16 = 111,
|
||||
EVM_INS_PUSH17 = 112,
|
||||
EVM_INS_PUSH18 = 113,
|
||||
EVM_INS_PUSH19 = 114,
|
||||
EVM_INS_PUSH20 = 115,
|
||||
EVM_INS_PUSH21 = 116,
|
||||
EVM_INS_PUSH22 = 117,
|
||||
EVM_INS_PUSH23 = 118,
|
||||
EVM_INS_PUSH24 = 119,
|
||||
EVM_INS_PUSH25 = 120,
|
||||
EVM_INS_PUSH26 = 121,
|
||||
EVM_INS_PUSH27 = 122,
|
||||
EVM_INS_PUSH28 = 123,
|
||||
EVM_INS_PUSH29 = 124,
|
||||
EVM_INS_PUSH30 = 125,
|
||||
EVM_INS_PUSH31 = 126,
|
||||
EVM_INS_PUSH32 = 127,
|
||||
EVM_INS_DUP1 = 128,
|
||||
EVM_INS_DUP2 = 129,
|
||||
EVM_INS_DUP3 = 130,
|
||||
EVM_INS_DUP4 = 131,
|
||||
EVM_INS_DUP5 = 132,
|
||||
EVM_INS_DUP6 = 133,
|
||||
EVM_INS_DUP7 = 134,
|
||||
EVM_INS_DUP8 = 135,
|
||||
EVM_INS_DUP9 = 136,
|
||||
EVM_INS_DUP10 = 137,
|
||||
EVM_INS_DUP11 = 138,
|
||||
EVM_INS_DUP12 = 139,
|
||||
EVM_INS_DUP13 = 140,
|
||||
EVM_INS_DUP14 = 141,
|
||||
EVM_INS_DUP15 = 142,
|
||||
EVM_INS_DUP16 = 143,
|
||||
EVM_INS_SWAP1 = 144,
|
||||
EVM_INS_SWAP2 = 145,
|
||||
EVM_INS_SWAP3 = 146,
|
||||
EVM_INS_SWAP4 = 147,
|
||||
EVM_INS_SWAP5 = 148,
|
||||
EVM_INS_SWAP6 = 149,
|
||||
EVM_INS_SWAP7 = 150,
|
||||
EVM_INS_SWAP8 = 151,
|
||||
EVM_INS_SWAP9 = 152,
|
||||
EVM_INS_SWAP10 = 153,
|
||||
EVM_INS_SWAP11 = 154,
|
||||
EVM_INS_SWAP12 = 155,
|
||||
EVM_INS_SWAP13 = 156,
|
||||
EVM_INS_SWAP14 = 157,
|
||||
EVM_INS_SWAP15 = 158,
|
||||
EVM_INS_SWAP16 = 159,
|
||||
EVM_INS_LOG0 = 160,
|
||||
EVM_INS_LOG1 = 161,
|
||||
EVM_INS_LOG2 = 162,
|
||||
EVM_INS_LOG3 = 163,
|
||||
EVM_INS_LOG4 = 164,
|
||||
EVM_INS_CREATE = 240,
|
||||
EVM_INS_CALL = 241,
|
||||
EVM_INS_CALLCODE = 242,
|
||||
EVM_INS_RETURN = 243,
|
||||
EVM_INS_DELEGATECALL = 244,
|
||||
EVM_INS_CALLBLACKBOX = 245,
|
||||
EVM_INS_STATICCALL = 250,
|
||||
EVM_INS_REVERT = 253,
|
||||
EVM_INS_SUICIDE = 255,
|
||||
|
||||
EVM_INS_INVALID = 512,
|
||||
EVM_INS_ENDING, // <-- mark the end of the list of instructions
|
||||
} evm_insn;
|
||||
|
||||
/// Group of EVM instructions
|
||||
typedef enum evm_insn_group {
|
||||
EVM_GRP_INVALID = 0, ///< = CS_GRP_INVALID
|
||||
|
||||
EVM_GRP_JUMP, ///< all jump instructions
|
||||
|
||||
EVM_GRP_MATH = 8, ///< math instructions
|
||||
EVM_GRP_STACK_WRITE, ///< instructions write to stack
|
||||
EVM_GRP_STACK_READ, ///< instructions read from stack
|
||||
EVM_GRP_MEM_WRITE, ///< instructions write to memory
|
||||
EVM_GRP_MEM_READ, ///< instructions read from memory
|
||||
EVM_GRP_STORE_WRITE, ///< instructions write to storage
|
||||
EVM_GRP_STORE_READ, ///< instructions read from storage
|
||||
EVM_GRP_HALT, ///< instructions halt execution
|
||||
|
||||
EVM_GRP_ENDING, ///< <-- mark the end of the list of groups
|
||||
} evm_insn_group;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,537 @@
|
||||
#ifndef CAPSTONE_M680X_H
|
||||
#define CAPSTONE_M680X_H
|
||||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* M680X Backend by Wolfgang Schwotzer <wolfgang.schwotzer@gmx.net> 2017 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
#define M680X_OPERAND_COUNT 9
|
||||
|
||||
/// M680X registers and special registers
|
||||
typedef enum m680x_reg {
|
||||
M680X_REG_INVALID = 0,
|
||||
|
||||
M680X_REG_A, ///< M6800/1/2/3/9, HD6301/9
|
||||
M680X_REG_B, ///< M6800/1/2/3/9, HD6301/9
|
||||
M680X_REG_E, ///< HD6309
|
||||
M680X_REG_F, ///< HD6309
|
||||
M680X_REG_0, ///< HD6309
|
||||
|
||||
M680X_REG_D, ///< M6801/3/9, HD6301/9
|
||||
M680X_REG_W, ///< HD6309
|
||||
|
||||
M680X_REG_CC, ///< M6800/1/2/3/9, M6301/9
|
||||
M680X_REG_DP, ///< M6809/M6309
|
||||
M680X_REG_MD, ///< M6309
|
||||
|
||||
M680X_REG_HX, ///< M6808
|
||||
M680X_REG_H, ///< M6808
|
||||
M680X_REG_X, ///< M6800/1/2/3/9, M6301/9
|
||||
M680X_REG_Y, ///< M6809/M6309
|
||||
M680X_REG_S, ///< M6809/M6309
|
||||
M680X_REG_U, ///< M6809/M6309
|
||||
M680X_REG_V, ///< M6309
|
||||
|
||||
M680X_REG_Q, ///< M6309
|
||||
|
||||
M680X_REG_PC, ///< M6800/1/2/3/9, M6301/9
|
||||
|
||||
M680X_REG_TMP2, ///< CPU12
|
||||
M680X_REG_TMP3, ///< CPU12
|
||||
|
||||
M680X_REG_ENDING, ///< <-- mark the end of the list of registers
|
||||
} m680x_reg;
|
||||
|
||||
/// Operand type for instruction's operands
|
||||
typedef enum m680x_op_type {
|
||||
M680X_OP_INVALID = 0, ///< = CS_OP_INVALID (Uninitialized).
|
||||
M680X_OP_REGISTER, ///< = Register operand.
|
||||
M680X_OP_IMMEDIATE, ///< = Immediate operand.
|
||||
M680X_OP_INDEXED, ///< = Indexed addressing operand.
|
||||
M680X_OP_EXTENDED, ///< = Extended addressing operand.
|
||||
M680X_OP_DIRECT, ///< = Direct addressing operand.
|
||||
M680X_OP_RELATIVE, ///< = Relative addressing operand.
|
||||
M680X_OP_CONSTANT, ///< = constant operand (Displayed as number only).
|
||||
///< Used e.g. for a bit index or page number.
|
||||
} m680x_op_type;
|
||||
|
||||
// Supported bit values for mem.idx.offset_bits
|
||||
#define M680X_OFFSET_NONE 0
|
||||
#define M680X_OFFSET_BITS_5 5
|
||||
#define M680X_OFFSET_BITS_8 8
|
||||
#define M680X_OFFSET_BITS_9 9
|
||||
#define M680X_OFFSET_BITS_16 16
|
||||
|
||||
// Supported bit flags for mem.idx.flags
|
||||
// These flags can be combined
|
||||
#define M680X_IDX_INDIRECT 1
|
||||
#define M680X_IDX_NO_COMMA 2
|
||||
#define M680X_IDX_POST_INC_DEC 4
|
||||
|
||||
/// Instruction's operand referring to indexed addressing
|
||||
typedef struct m680x_op_idx {
|
||||
m680x_reg base_reg; ///< base register (or M680X_REG_INVALID if
|
||||
///< irrelevant)
|
||||
m680x_reg offset_reg; ///< offset register (or M680X_REG_INVALID if
|
||||
///< irrelevant)
|
||||
int16_t offset; ///< 5-,8- or 16-bit offset. See also offset_bits.
|
||||
uint16_t offset_addr; ///< = offset addr. if base_reg == M680X_REG_PC.
|
||||
///< calculated as offset + PC
|
||||
uint8_t offset_bits; ///< offset width in bits for indexed addressing
|
||||
int8_t inc_dec; ///< inc. or dec. value:
|
||||
///< 0: no inc-/decrement
|
||||
///< 1 .. 8: increment by 1 .. 8
|
||||
///< -1 .. -8: decrement by 1 .. 8
|
||||
///< if flag M680X_IDX_POST_INC_DEC set it is post
|
||||
///< inc-/decrement otherwise pre inc-/decrement
|
||||
uint8_t flags; ///< 8-bit flags (see above)
|
||||
} m680x_op_idx;
|
||||
|
||||
/// Instruction's memory operand referring to relative addressing (Bcc/LBcc)
|
||||
typedef struct m680x_op_rel {
|
||||
uint16_t address; ///< The absolute address.
|
||||
///< calculated as PC + offset. PC is the first
|
||||
///< address after the instruction.
|
||||
int16_t offset; ///< the offset/displacement value
|
||||
} m680x_op_rel;
|
||||
|
||||
/// Instruction's operand referring to extended addressing
|
||||
typedef struct m680x_op_ext {
|
||||
uint16_t address; ///< The absolute address
|
||||
bool indirect; ///< true if extended indirect addressing
|
||||
} m680x_op_ext;
|
||||
|
||||
/// Instruction operand
|
||||
typedef struct cs_m680x_op {
|
||||
m680x_op_type type;
|
||||
union {
|
||||
int32_t imm; ///< immediate value for IMM operand
|
||||
m680x_reg reg; ///< register value for REG operand
|
||||
m680x_op_idx idx; ///< Indexed addressing operand
|
||||
m680x_op_rel rel; ///< Relative address. operand (Bcc/LBcc)
|
||||
m680x_op_ext ext; ///< Extended address
|
||||
uint8_t direct_addr; ///<</ Direct address (lower 8-bit)
|
||||
uint8_t const_val; ///< constant value (bit index, page nr.)
|
||||
};
|
||||
uint8_t size; ///< size of this operand (in bytes)
|
||||
/// How is this operand accessed? (READ, WRITE or READ|WRITE)
|
||||
/// This field is combined of cs_ac_type.
|
||||
/// NOTE: this field is irrelevant if engine is compiled in DIET
|
||||
uint8_t access;
|
||||
} cs_m680x_op;
|
||||
|
||||
/// Group of M680X instructions
|
||||
typedef enum m680x_group_type {
|
||||
M680X_GRP_INVALID = 0, /// = CS_GRP_INVALID
|
||||
// Generic groups
|
||||
// all jump instructions (conditional+direct+indirect jumps)
|
||||
M680X_GRP_JUMP, ///< = CS_GRP_JUMP
|
||||
// all call instructions
|
||||
M680X_GRP_CALL, ///< = CS_GRP_CALL
|
||||
// all return instructions
|
||||
M680X_GRP_RET, ///< = CS_GRP_RET
|
||||
// all interrupt instructions (int+syscall)
|
||||
M680X_GRP_INT, ///< = CS_GRP_INT
|
||||
// all interrupt return instructions
|
||||
M680X_GRP_IRET, ///< = CS_GRP_IRET
|
||||
// all privileged instructions
|
||||
M680X_GRP_PRIV, ///< = CS_GRP_PRIVILEDGE; not used
|
||||
// all relative branching instructions
|
||||
M680X_GRP_BRAREL, ///< = CS_GRP_BRANCH_RELATIVE
|
||||
|
||||
// Architecture-specific groups
|
||||
M680X_GRP_ENDING, // <-- mark the end of the list of groups
|
||||
} m680x_group_type;
|
||||
|
||||
// M680X instruction flags:
|
||||
|
||||
/// The first (register) operand is part of the
|
||||
/// instruction mnemonic
|
||||
#define M680X_FIRST_OP_IN_MNEM 1
|
||||
/// The second (register) operand is part of the
|
||||
/// instruction mnemonic
|
||||
#define M680X_SECOND_OP_IN_MNEM 2
|
||||
|
||||
/// The M680X instruction and it's operands
|
||||
typedef struct cs_m680x {
|
||||
uint8_t flags; ///< See: M680X instruction flags
|
||||
uint8_t op_count; ///< number of operands for the instruction or 0
|
||||
cs_m680x_op operands[M680X_OPERAND_COUNT]; ///< operands for this insn.
|
||||
} cs_m680x;
|
||||
|
||||
/// M680X instruction IDs
|
||||
typedef enum m680x_insn {
|
||||
M680X_INS_INVLD = 0,
|
||||
M680X_INS_ABA, ///< M6800/1/2/3
|
||||
M680X_INS_ABX,
|
||||
M680X_INS_ABY,
|
||||
M680X_INS_ADC,
|
||||
M680X_INS_ADCA,
|
||||
M680X_INS_ADCB,
|
||||
M680X_INS_ADCD,
|
||||
M680X_INS_ADCR,
|
||||
M680X_INS_ADD,
|
||||
M680X_INS_ADDA,
|
||||
M680X_INS_ADDB,
|
||||
M680X_INS_ADDD,
|
||||
M680X_INS_ADDE,
|
||||
M680X_INS_ADDF,
|
||||
M680X_INS_ADDR,
|
||||
M680X_INS_ADDW,
|
||||
M680X_INS_AIM,
|
||||
M680X_INS_AIS,
|
||||
M680X_INS_AIX,
|
||||
M680X_INS_AND,
|
||||
M680X_INS_ANDA,
|
||||
M680X_INS_ANDB,
|
||||
M680X_INS_ANDCC,
|
||||
M680X_INS_ANDD,
|
||||
M680X_INS_ANDR,
|
||||
M680X_INS_ASL,
|
||||
M680X_INS_ASLA,
|
||||
M680X_INS_ASLB,
|
||||
M680X_INS_ASLD, ///< or LSLD
|
||||
M680X_INS_ASR,
|
||||
M680X_INS_ASRA,
|
||||
M680X_INS_ASRB,
|
||||
M680X_INS_ASRD,
|
||||
M680X_INS_ASRX,
|
||||
M680X_INS_BAND,
|
||||
M680X_INS_BCC, ///< or BHS
|
||||
M680X_INS_BCLR,
|
||||
M680X_INS_BCS, ///< or BLO
|
||||
M680X_INS_BEOR,
|
||||
M680X_INS_BEQ,
|
||||
M680X_INS_BGE,
|
||||
M680X_INS_BGND,
|
||||
M680X_INS_BGT,
|
||||
M680X_INS_BHCC,
|
||||
M680X_INS_BHCS,
|
||||
M680X_INS_BHI,
|
||||
M680X_INS_BIAND,
|
||||
M680X_INS_BIEOR,
|
||||
M680X_INS_BIH,
|
||||
M680X_INS_BIL,
|
||||
M680X_INS_BIOR,
|
||||
M680X_INS_BIT,
|
||||
M680X_INS_BITA,
|
||||
M680X_INS_BITB,
|
||||
M680X_INS_BITD,
|
||||
M680X_INS_BITMD,
|
||||
M680X_INS_BLE,
|
||||
M680X_INS_BLS,
|
||||
M680X_INS_BLT,
|
||||
M680X_INS_BMC,
|
||||
M680X_INS_BMI,
|
||||
M680X_INS_BMS,
|
||||
M680X_INS_BNE,
|
||||
M680X_INS_BOR,
|
||||
M680X_INS_BPL,
|
||||
M680X_INS_BRCLR,
|
||||
M680X_INS_BRSET,
|
||||
M680X_INS_BRA,
|
||||
M680X_INS_BRN,
|
||||
M680X_INS_BSET,
|
||||
M680X_INS_BSR,
|
||||
M680X_INS_BVC,
|
||||
M680X_INS_BVS,
|
||||
M680X_INS_CALL,
|
||||
M680X_INS_CBA, ///< M6800/1/2/3
|
||||
M680X_INS_CBEQ,
|
||||
M680X_INS_CBEQA,
|
||||
M680X_INS_CBEQX,
|
||||
M680X_INS_CLC, ///< M6800/1/2/3
|
||||
M680X_INS_CLI, ///< M6800/1/2/3
|
||||
M680X_INS_CLR,
|
||||
M680X_INS_CLRA,
|
||||
M680X_INS_CLRB,
|
||||
M680X_INS_CLRD,
|
||||
M680X_INS_CLRE,
|
||||
M680X_INS_CLRF,
|
||||
M680X_INS_CLRH,
|
||||
M680X_INS_CLRW,
|
||||
M680X_INS_CLRX,
|
||||
M680X_INS_CLV, ///< M6800/1/2/3
|
||||
M680X_INS_CMP,
|
||||
M680X_INS_CMPA,
|
||||
M680X_INS_CMPB,
|
||||
M680X_INS_CMPD,
|
||||
M680X_INS_CMPE,
|
||||
M680X_INS_CMPF,
|
||||
M680X_INS_CMPR,
|
||||
M680X_INS_CMPS,
|
||||
M680X_INS_CMPU,
|
||||
M680X_INS_CMPW,
|
||||
M680X_INS_CMPX,
|
||||
M680X_INS_CMPY,
|
||||
M680X_INS_COM,
|
||||
M680X_INS_COMA,
|
||||
M680X_INS_COMB,
|
||||
M680X_INS_COMD,
|
||||
M680X_INS_COME,
|
||||
M680X_INS_COMF,
|
||||
M680X_INS_COMW,
|
||||
M680X_INS_COMX,
|
||||
M680X_INS_CPD,
|
||||
M680X_INS_CPHX,
|
||||
M680X_INS_CPS,
|
||||
M680X_INS_CPX, ///< M6800/1/2/3
|
||||
M680X_INS_CPY,
|
||||
M680X_INS_CWAI,
|
||||
M680X_INS_DAA,
|
||||
M680X_INS_DBEQ,
|
||||
M680X_INS_DBNE,
|
||||
M680X_INS_DBNZ,
|
||||
M680X_INS_DBNZA,
|
||||
M680X_INS_DBNZX,
|
||||
M680X_INS_DEC,
|
||||
M680X_INS_DECA,
|
||||
M680X_INS_DECB,
|
||||
M680X_INS_DECD,
|
||||
M680X_INS_DECE,
|
||||
M680X_INS_DECF,
|
||||
M680X_INS_DECW,
|
||||
M680X_INS_DECX,
|
||||
M680X_INS_DES, ///< M6800/1/2/3
|
||||
M680X_INS_DEX, ///< M6800/1/2/3
|
||||
M680X_INS_DEY,
|
||||
M680X_INS_DIV,
|
||||
M680X_INS_DIVD,
|
||||
M680X_INS_DIVQ,
|
||||
M680X_INS_EDIV,
|
||||
M680X_INS_EDIVS,
|
||||
M680X_INS_EIM,
|
||||
M680X_INS_EMACS,
|
||||
M680X_INS_EMAXD,
|
||||
M680X_INS_EMAXM,
|
||||
M680X_INS_EMIND,
|
||||
M680X_INS_EMINM,
|
||||
M680X_INS_EMUL,
|
||||
M680X_INS_EMULS,
|
||||
M680X_INS_EOR,
|
||||
M680X_INS_EORA,
|
||||
M680X_INS_EORB,
|
||||
M680X_INS_EORD,
|
||||
M680X_INS_EORR,
|
||||
M680X_INS_ETBL,
|
||||
M680X_INS_EXG,
|
||||
M680X_INS_FDIV,
|
||||
M680X_INS_IBEQ,
|
||||
M680X_INS_IBNE,
|
||||
M680X_INS_IDIV,
|
||||
M680X_INS_IDIVS,
|
||||
M680X_INS_ILLGL,
|
||||
M680X_INS_INC,
|
||||
M680X_INS_INCA,
|
||||
M680X_INS_INCB,
|
||||
M680X_INS_INCD,
|
||||
M680X_INS_INCE,
|
||||
M680X_INS_INCF,
|
||||
M680X_INS_INCW,
|
||||
M680X_INS_INCX,
|
||||
M680X_INS_INS, ///< M6800/1/2/3
|
||||
M680X_INS_INX, ///< M6800/1/2/3
|
||||
M680X_INS_INY,
|
||||
M680X_INS_JMP,
|
||||
M680X_INS_JSR,
|
||||
M680X_INS_LBCC, ///< or LBHS
|
||||
M680X_INS_LBCS, ///< or LBLO
|
||||
M680X_INS_LBEQ,
|
||||
M680X_INS_LBGE,
|
||||
M680X_INS_LBGT,
|
||||
M680X_INS_LBHI,
|
||||
M680X_INS_LBLE,
|
||||
M680X_INS_LBLS,
|
||||
M680X_INS_LBLT,
|
||||
M680X_INS_LBMI,
|
||||
M680X_INS_LBNE,
|
||||
M680X_INS_LBPL,
|
||||
M680X_INS_LBRA,
|
||||
M680X_INS_LBRN,
|
||||
M680X_INS_LBSR,
|
||||
M680X_INS_LBVC,
|
||||
M680X_INS_LBVS,
|
||||
M680X_INS_LDA,
|
||||
M680X_INS_LDAA, ///< M6800/1/2/3
|
||||
M680X_INS_LDAB, ///< M6800/1/2/3
|
||||
M680X_INS_LDB,
|
||||
M680X_INS_LDBT,
|
||||
M680X_INS_LDD,
|
||||
M680X_INS_LDE,
|
||||
M680X_INS_LDF,
|
||||
M680X_INS_LDHX,
|
||||
M680X_INS_LDMD,
|
||||
M680X_INS_LDQ,
|
||||
M680X_INS_LDS,
|
||||
M680X_INS_LDU,
|
||||
M680X_INS_LDW,
|
||||
M680X_INS_LDX,
|
||||
M680X_INS_LDY,
|
||||
M680X_INS_LEAS,
|
||||
M680X_INS_LEAU,
|
||||
M680X_INS_LEAX,
|
||||
M680X_INS_LEAY,
|
||||
M680X_INS_LSL,
|
||||
M680X_INS_LSLA,
|
||||
M680X_INS_LSLB,
|
||||
M680X_INS_LSLD,
|
||||
M680X_INS_LSLX,
|
||||
M680X_INS_LSR,
|
||||
M680X_INS_LSRA,
|
||||
M680X_INS_LSRB,
|
||||
M680X_INS_LSRD, ///< or ASRD
|
||||
M680X_INS_LSRW,
|
||||
M680X_INS_LSRX,
|
||||
M680X_INS_MAXA,
|
||||
M680X_INS_MAXM,
|
||||
M680X_INS_MEM,
|
||||
M680X_INS_MINA,
|
||||
M680X_INS_MINM,
|
||||
M680X_INS_MOV,
|
||||
M680X_INS_MOVB,
|
||||
M680X_INS_MOVW,
|
||||
M680X_INS_MUL,
|
||||
M680X_INS_MULD,
|
||||
M680X_INS_NEG,
|
||||
M680X_INS_NEGA,
|
||||
M680X_INS_NEGB,
|
||||
M680X_INS_NEGD,
|
||||
M680X_INS_NEGX,
|
||||
M680X_INS_NOP,
|
||||
M680X_INS_NSA,
|
||||
M680X_INS_OIM,
|
||||
M680X_INS_ORA,
|
||||
M680X_INS_ORAA, ///< M6800/1/2/3
|
||||
M680X_INS_ORAB, ///< M6800/1/2/3
|
||||
M680X_INS_ORB,
|
||||
M680X_INS_ORCC,
|
||||
M680X_INS_ORD,
|
||||
M680X_INS_ORR,
|
||||
M680X_INS_PSHA, ///< M6800/1/2/3
|
||||
M680X_INS_PSHB, ///< M6800/1/2/3
|
||||
M680X_INS_PSHC,
|
||||
M680X_INS_PSHD,
|
||||
M680X_INS_PSHH,
|
||||
M680X_INS_PSHS,
|
||||
M680X_INS_PSHSW,
|
||||
M680X_INS_PSHU,
|
||||
M680X_INS_PSHUW,
|
||||
M680X_INS_PSHX, ///< M6800/1/2/3
|
||||
M680X_INS_PSHY,
|
||||
M680X_INS_PULA, ///< M6800/1/2/3
|
||||
M680X_INS_PULB, ///< M6800/1/2/3
|
||||
M680X_INS_PULC,
|
||||
M680X_INS_PULD,
|
||||
M680X_INS_PULH,
|
||||
M680X_INS_PULS,
|
||||
M680X_INS_PULSW,
|
||||
M680X_INS_PULU,
|
||||
M680X_INS_PULUW,
|
||||
M680X_INS_PULX, ///< M6800/1/2/3
|
||||
M680X_INS_PULY,
|
||||
M680X_INS_REV,
|
||||
M680X_INS_REVW,
|
||||
M680X_INS_ROL,
|
||||
M680X_INS_ROLA,
|
||||
M680X_INS_ROLB,
|
||||
M680X_INS_ROLD,
|
||||
M680X_INS_ROLW,
|
||||
M680X_INS_ROLX,
|
||||
M680X_INS_ROR,
|
||||
M680X_INS_RORA,
|
||||
M680X_INS_RORB,
|
||||
M680X_INS_RORD,
|
||||
M680X_INS_RORW,
|
||||
M680X_INS_RORX,
|
||||
M680X_INS_RSP,
|
||||
M680X_INS_RTC,
|
||||
M680X_INS_RTI,
|
||||
M680X_INS_RTS,
|
||||
M680X_INS_SBA, ///< M6800/1/2/3
|
||||
M680X_INS_SBC,
|
||||
M680X_INS_SBCA,
|
||||
M680X_INS_SBCB,
|
||||
M680X_INS_SBCD,
|
||||
M680X_INS_SBCR,
|
||||
M680X_INS_SEC,
|
||||
M680X_INS_SEI,
|
||||
M680X_INS_SEV,
|
||||
M680X_INS_SEX,
|
||||
M680X_INS_SEXW,
|
||||
M680X_INS_SLP,
|
||||
M680X_INS_STA,
|
||||
M680X_INS_STAA, ///< M6800/1/2/3
|
||||
M680X_INS_STAB, ///< M6800/1/2/3
|
||||
M680X_INS_STB,
|
||||
M680X_INS_STBT,
|
||||
M680X_INS_STD,
|
||||
M680X_INS_STE,
|
||||
M680X_INS_STF,
|
||||
M680X_INS_STOP,
|
||||
M680X_INS_STHX,
|
||||
M680X_INS_STQ,
|
||||
M680X_INS_STS,
|
||||
M680X_INS_STU,
|
||||
M680X_INS_STW,
|
||||
M680X_INS_STX,
|
||||
M680X_INS_STY,
|
||||
M680X_INS_SUB,
|
||||
M680X_INS_SUBA,
|
||||
M680X_INS_SUBB,
|
||||
M680X_INS_SUBD,
|
||||
M680X_INS_SUBE,
|
||||
M680X_INS_SUBF,
|
||||
M680X_INS_SUBR,
|
||||
M680X_INS_SUBW,
|
||||
M680X_INS_SWI,
|
||||
M680X_INS_SWI2,
|
||||
M680X_INS_SWI3,
|
||||
M680X_INS_SYNC,
|
||||
M680X_INS_TAB, ///< M6800/1/2/3
|
||||
M680X_INS_TAP, ///< M6800/1/2/3
|
||||
M680X_INS_TAX,
|
||||
M680X_INS_TBA, ///< M6800/1/2/3
|
||||
M680X_INS_TBEQ,
|
||||
M680X_INS_TBL,
|
||||
M680X_INS_TBNE,
|
||||
M680X_INS_TEST,
|
||||
M680X_INS_TFM,
|
||||
M680X_INS_TFR,
|
||||
M680X_INS_TIM,
|
||||
M680X_INS_TPA, ///< M6800/1/2/3
|
||||
M680X_INS_TST,
|
||||
M680X_INS_TSTA,
|
||||
M680X_INS_TSTB,
|
||||
M680X_INS_TSTD,
|
||||
M680X_INS_TSTE,
|
||||
M680X_INS_TSTF,
|
||||
M680X_INS_TSTW,
|
||||
M680X_INS_TSTX,
|
||||
M680X_INS_TSX, ///< M6800/1/2/3
|
||||
M680X_INS_TSY,
|
||||
M680X_INS_TXA,
|
||||
M680X_INS_TXS, ///< M6800/1/2/3
|
||||
M680X_INS_TYS,
|
||||
M680X_INS_WAI, ///< M6800/1/2/3
|
||||
M680X_INS_WAIT,
|
||||
M680X_INS_WAV,
|
||||
M680X_INS_WAVR,
|
||||
M680X_INS_XGDX, ///< HD6301
|
||||
M680X_INS_XGDY,
|
||||
M680X_INS_ENDING, // <-- mark the end of the list of instructions
|
||||
} m680x_insn;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,610 @@
|
||||
#ifndef CAPSTONE_M68K_H
|
||||
#define CAPSTONE_M68K_H
|
||||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Daniel Collin <daniel@collin.com>, 2015-2016 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
#define M68K_OPERAND_COUNT 4
|
||||
|
||||
/// M68K registers and special registers
|
||||
typedef enum m68k_reg {
|
||||
M68K_REG_INVALID = 0,
|
||||
|
||||
M68K_REG_D0,
|
||||
M68K_REG_D1,
|
||||
M68K_REG_D2,
|
||||
M68K_REG_D3,
|
||||
M68K_REG_D4,
|
||||
M68K_REG_D5,
|
||||
M68K_REG_D6,
|
||||
M68K_REG_D7,
|
||||
|
||||
M68K_REG_A0,
|
||||
M68K_REG_A1,
|
||||
M68K_REG_A2,
|
||||
M68K_REG_A3,
|
||||
M68K_REG_A4,
|
||||
M68K_REG_A5,
|
||||
M68K_REG_A6,
|
||||
M68K_REG_A7,
|
||||
|
||||
M68K_REG_FP0,
|
||||
M68K_REG_FP1,
|
||||
M68K_REG_FP2,
|
||||
M68K_REG_FP3,
|
||||
M68K_REG_FP4,
|
||||
M68K_REG_FP5,
|
||||
M68K_REG_FP6,
|
||||
M68K_REG_FP7,
|
||||
|
||||
M68K_REG_PC,
|
||||
|
||||
M68K_REG_SR,
|
||||
M68K_REG_CCR,
|
||||
M68K_REG_SFC,
|
||||
M68K_REG_DFC,
|
||||
M68K_REG_USP,
|
||||
M68K_REG_VBR,
|
||||
M68K_REG_CACR,
|
||||
M68K_REG_CAAR,
|
||||
M68K_REG_MSP,
|
||||
M68K_REG_ISP,
|
||||
M68K_REG_TC,
|
||||
M68K_REG_ITT0,
|
||||
M68K_REG_ITT1,
|
||||
M68K_REG_DTT0,
|
||||
M68K_REG_DTT1,
|
||||
M68K_REG_MMUSR,
|
||||
M68K_REG_URP,
|
||||
M68K_REG_SRP,
|
||||
|
||||
M68K_REG_FPCR,
|
||||
M68K_REG_FPSR,
|
||||
M68K_REG_FPIAR,
|
||||
|
||||
M68K_REG_ENDING, // <-- mark the end of the list of registers
|
||||
} m68k_reg;
|
||||
|
||||
/// M68K Addressing Modes
|
||||
typedef enum m68k_address_mode {
|
||||
M68K_AM_NONE = 0, ///< No address mode.
|
||||
|
||||
M68K_AM_REG_DIRECT_DATA, ///< Register Direct - Data
|
||||
M68K_AM_REG_DIRECT_ADDR, ///< Register Direct - Address
|
||||
|
||||
M68K_AM_REGI_ADDR, ///< Register Indirect - Address
|
||||
M68K_AM_REGI_ADDR_POST_INC, ///< Register Indirect - Address with Postincrement
|
||||
M68K_AM_REGI_ADDR_PRE_DEC, ///< Register Indirect - Address with Predecrement
|
||||
M68K_AM_REGI_ADDR_DISP, ///< Register Indirect - Address with Displacement
|
||||
|
||||
M68K_AM_AREGI_INDEX_8_BIT_DISP, ///< Address Register Indirect With Index- 8-bit displacement
|
||||
M68K_AM_AREGI_INDEX_BASE_DISP, ///< Address Register Indirect With Index- Base displacement
|
||||
|
||||
M68K_AM_MEMI_POST_INDEX, ///< Memory indirect - Postindex
|
||||
M68K_AM_MEMI_PRE_INDEX, ///< Memory indirect - Preindex
|
||||
|
||||
M68K_AM_PCI_DISP, ///< Program Counter Indirect - with Displacement
|
||||
|
||||
M68K_AM_PCI_INDEX_8_BIT_DISP, ///< Program Counter Indirect with Index - with 8-Bit Displacement
|
||||
M68K_AM_PCI_INDEX_BASE_DISP, ///< Program Counter Indirect with Index - with Base Displacement
|
||||
|
||||
M68K_AM_PC_MEMI_POST_INDEX, ///< Program Counter Memory Indirect - Postindexed
|
||||
M68K_AM_PC_MEMI_PRE_INDEX, ///< Program Counter Memory Indirect - Preindexed
|
||||
|
||||
M68K_AM_ABSOLUTE_DATA_SHORT, ///< Absolute Data Addressing - Short
|
||||
M68K_AM_ABSOLUTE_DATA_LONG, ///< Absolute Data Addressing - Long
|
||||
M68K_AM_IMMEDIATE, ///< Immediate value
|
||||
|
||||
M68K_AM_BRANCH_DISPLACEMENT, ///< Address as displacement from (PC+2) used by branches
|
||||
} m68k_address_mode;
|
||||
|
||||
/// Operand type for instruction's operands
|
||||
typedef enum m68k_op_type {
|
||||
M68K_OP_INVALID = 0, ///< = CS_OP_INVALID (Uninitialized).
|
||||
M68K_OP_REG, ///< = CS_OP_REG (Register operand).
|
||||
M68K_OP_IMM, ///< = CS_OP_IMM (Immediate operand).
|
||||
M68K_OP_MEM, ///< = CS_OP_MEM (Memory operand).
|
||||
M68K_OP_FP_SINGLE, ///< single precision Floating-Point operand
|
||||
M68K_OP_FP_DOUBLE, ///< double precision Floating-Point operand
|
||||
M68K_OP_REG_BITS, ///< Register bits move
|
||||
M68K_OP_REG_PAIR, ///< Register pair in the same op (upper 4 bits for first reg, lower for second)
|
||||
M68K_OP_BR_DISP, ///< Branch displacement
|
||||
} m68k_op_type;
|
||||
|
||||
/// Instruction's operand referring to memory
|
||||
/// This is associated with M68K_OP_MEM operand type above
|
||||
typedef struct m68k_op_mem {
|
||||
m68k_reg base_reg; ///< base register (or M68K_REG_INVALID if irrelevant)
|
||||
m68k_reg index_reg; ///< index register (or M68K_REG_INVALID if irrelevant)
|
||||
m68k_reg in_base_reg; ///< indirect base register (or M68K_REG_INVALID if irrelevant)
|
||||
uint32_t in_disp; ///< indirect displacement
|
||||
uint32_t out_disp; ///< other displacement
|
||||
int16_t disp; ///< displacement value
|
||||
uint8_t scale; ///< scale for index register
|
||||
uint8_t bitfield; ///< set to true if the two values below should be used
|
||||
uint8_t width; ///< used for bf* instructions
|
||||
uint8_t offset; ///< used for bf* instructions
|
||||
uint8_t index_size; ///< 0 = w, 1 = l
|
||||
} m68k_op_mem;
|
||||
|
||||
/// Operand type for instruction's operands
|
||||
typedef enum m68k_op_br_disp_size {
|
||||
M68K_OP_BR_DISP_SIZE_INVALID = 0, ///< = CS_OP_INVALID (Uninitialized).
|
||||
M68K_OP_BR_DISP_SIZE_BYTE = 1, ///< signed 8-bit displacement
|
||||
M68K_OP_BR_DISP_SIZE_WORD = 2, ///< signed 16-bit displacement
|
||||
M68K_OP_BR_DISP_SIZE_LONG = 4, ///< signed 32-bit displacement
|
||||
} m68k_op_br_disp_size;
|
||||
|
||||
typedef struct m68k_op_br_disp {
|
||||
int32_t disp; ///< displacement value
|
||||
uint8_t disp_size; ///< Size from m68k_op_br_disp_size type above
|
||||
} m68k_op_br_disp;
|
||||
|
||||
/// Instruction operand
|
||||
typedef struct cs_m68k_op {
|
||||
union {
|
||||
uint64_t imm; ///< immediate value for IMM operand
|
||||
double dimm; ///< double imm
|
||||
float simm; ///< float imm
|
||||
m68k_reg reg; ///< register value for REG operand
|
||||
struct { ///< register pair in one operand
|
||||
m68k_reg reg_0;
|
||||
m68k_reg reg_1;
|
||||
} reg_pair;
|
||||
};
|
||||
|
||||
m68k_op_mem mem; ///< data when operand is targeting memory
|
||||
m68k_op_br_disp br_disp; ///< data when operand is a branch displacement
|
||||
uint32_t register_bits; ///< register bits for movem etc. (always in d0-d7, a0-a7, fp0 - fp7 order)
|
||||
m68k_op_type type;
|
||||
m68k_address_mode address_mode; ///< M68K addressing mode for this op
|
||||
} cs_m68k_op;
|
||||
|
||||
/// Operation size of the CPU instructions
|
||||
typedef enum m68k_cpu_size {
|
||||
M68K_CPU_SIZE_NONE = 0, ///< unsized or unspecified
|
||||
M68K_CPU_SIZE_BYTE = 1, ///< 1 byte in size
|
||||
M68K_CPU_SIZE_WORD = 2, ///< 2 bytes in size
|
||||
M68K_CPU_SIZE_LONG = 4, ///< 4 bytes in size
|
||||
} m68k_cpu_size;
|
||||
|
||||
/// Operation size of the FPU instructions (Notice that FPU instruction can also use CPU sizes if needed)
|
||||
typedef enum m68k_fpu_size {
|
||||
M68K_FPU_SIZE_NONE = 0, ///< unsized like fsave/frestore
|
||||
M68K_FPU_SIZE_SINGLE = 4, ///< 4 byte in size (single float)
|
||||
M68K_FPU_SIZE_DOUBLE = 8, ///< 8 byte in size (double)
|
||||
M68K_FPU_SIZE_EXTENDED = 12, ///< 12 byte in size (extended real format)
|
||||
} m68k_fpu_size;
|
||||
|
||||
/// Type of size that is being used for the current instruction
|
||||
typedef enum m68k_size_type {
|
||||
M68K_SIZE_TYPE_INVALID = 0,
|
||||
|
||||
M68K_SIZE_TYPE_CPU,
|
||||
M68K_SIZE_TYPE_FPU,
|
||||
} m68k_size_type;
|
||||
|
||||
/// Operation size of the current instruction (NOT the actually size of instruction)
|
||||
typedef struct m68k_op_size {
|
||||
m68k_size_type type;
|
||||
union {
|
||||
m68k_cpu_size cpu_size;
|
||||
m68k_fpu_size fpu_size;
|
||||
};
|
||||
} m68k_op_size;
|
||||
|
||||
/// The M68K instruction and it's operands
|
||||
typedef struct cs_m68k {
|
||||
// Number of operands of this instruction or 0 when instruction has no operand.
|
||||
cs_m68k_op operands[M68K_OPERAND_COUNT]; ///< operands for this instruction.
|
||||
m68k_op_size op_size; ///< size of data operand works on in bytes (.b, .w, .l, etc)
|
||||
uint8_t op_count; ///< number of operands for the instruction
|
||||
} cs_m68k;
|
||||
|
||||
/// M68K instruction
|
||||
typedef enum m68k_insn {
|
||||
M68K_INS_INVALID = 0,
|
||||
|
||||
M68K_INS_ABCD,
|
||||
M68K_INS_ADD,
|
||||
M68K_INS_ADDA,
|
||||
M68K_INS_ADDI,
|
||||
M68K_INS_ADDQ,
|
||||
M68K_INS_ADDX,
|
||||
M68K_INS_AND,
|
||||
M68K_INS_ANDI,
|
||||
M68K_INS_ASL,
|
||||
M68K_INS_ASR,
|
||||
M68K_INS_BHS,
|
||||
M68K_INS_BLO,
|
||||
M68K_INS_BHI,
|
||||
M68K_INS_BLS,
|
||||
M68K_INS_BCC,
|
||||
M68K_INS_BCS,
|
||||
M68K_INS_BNE,
|
||||
M68K_INS_BEQ,
|
||||
M68K_INS_BVC,
|
||||
M68K_INS_BVS,
|
||||
M68K_INS_BPL,
|
||||
M68K_INS_BMI,
|
||||
M68K_INS_BGE,
|
||||
M68K_INS_BLT,
|
||||
M68K_INS_BGT,
|
||||
M68K_INS_BLE,
|
||||
M68K_INS_BRA,
|
||||
M68K_INS_BSR,
|
||||
M68K_INS_BCHG,
|
||||
M68K_INS_BCLR,
|
||||
M68K_INS_BSET,
|
||||
M68K_INS_BTST,
|
||||
M68K_INS_BFCHG,
|
||||
M68K_INS_BFCLR,
|
||||
M68K_INS_BFEXTS,
|
||||
M68K_INS_BFEXTU,
|
||||
M68K_INS_BFFFO,
|
||||
M68K_INS_BFINS,
|
||||
M68K_INS_BFSET,
|
||||
M68K_INS_BFTST,
|
||||
M68K_INS_BKPT,
|
||||
M68K_INS_CALLM,
|
||||
M68K_INS_CAS,
|
||||
M68K_INS_CAS2,
|
||||
M68K_INS_CHK,
|
||||
M68K_INS_CHK2,
|
||||
M68K_INS_CLR,
|
||||
M68K_INS_CMP,
|
||||
M68K_INS_CMPA,
|
||||
M68K_INS_CMPI,
|
||||
M68K_INS_CMPM,
|
||||
M68K_INS_CMP2,
|
||||
M68K_INS_CINVL,
|
||||
M68K_INS_CINVP,
|
||||
M68K_INS_CINVA,
|
||||
M68K_INS_CPUSHL,
|
||||
M68K_INS_CPUSHP,
|
||||
M68K_INS_CPUSHA,
|
||||
M68K_INS_DBT,
|
||||
M68K_INS_DBF,
|
||||
M68K_INS_DBHI,
|
||||
M68K_INS_DBLS,
|
||||
M68K_INS_DBCC,
|
||||
M68K_INS_DBCS,
|
||||
M68K_INS_DBNE,
|
||||
M68K_INS_DBEQ,
|
||||
M68K_INS_DBVC,
|
||||
M68K_INS_DBVS,
|
||||
M68K_INS_DBPL,
|
||||
M68K_INS_DBMI,
|
||||
M68K_INS_DBGE,
|
||||
M68K_INS_DBLT,
|
||||
M68K_INS_DBGT,
|
||||
M68K_INS_DBLE,
|
||||
M68K_INS_DBRA,
|
||||
M68K_INS_DIVS,
|
||||
M68K_INS_DIVSL,
|
||||
M68K_INS_DIVU,
|
||||
M68K_INS_DIVUL,
|
||||
M68K_INS_EOR,
|
||||
M68K_INS_EORI,
|
||||
M68K_INS_EXG,
|
||||
M68K_INS_EXT,
|
||||
M68K_INS_EXTB,
|
||||
M68K_INS_FABS,
|
||||
M68K_INS_FSABS,
|
||||
M68K_INS_FDABS,
|
||||
M68K_INS_FACOS,
|
||||
M68K_INS_FADD,
|
||||
M68K_INS_FSADD,
|
||||
M68K_INS_FDADD,
|
||||
M68K_INS_FASIN,
|
||||
M68K_INS_FATAN,
|
||||
M68K_INS_FATANH,
|
||||
M68K_INS_FBF,
|
||||
M68K_INS_FBEQ,
|
||||
M68K_INS_FBOGT,
|
||||
M68K_INS_FBOGE,
|
||||
M68K_INS_FBOLT,
|
||||
M68K_INS_FBOLE,
|
||||
M68K_INS_FBOGL,
|
||||
M68K_INS_FBOR,
|
||||
M68K_INS_FBUN,
|
||||
M68K_INS_FBUEQ,
|
||||
M68K_INS_FBUGT,
|
||||
M68K_INS_FBUGE,
|
||||
M68K_INS_FBULT,
|
||||
M68K_INS_FBULE,
|
||||
M68K_INS_FBNE,
|
||||
M68K_INS_FBT,
|
||||
M68K_INS_FBSF,
|
||||
M68K_INS_FBSEQ,
|
||||
M68K_INS_FBGT,
|
||||
M68K_INS_FBGE,
|
||||
M68K_INS_FBLT,
|
||||
M68K_INS_FBLE,
|
||||
M68K_INS_FBGL,
|
||||
M68K_INS_FBGLE,
|
||||
M68K_INS_FBNGLE,
|
||||
M68K_INS_FBNGL,
|
||||
M68K_INS_FBNLE,
|
||||
M68K_INS_FBNLT,
|
||||
M68K_INS_FBNGE,
|
||||
M68K_INS_FBNGT,
|
||||
M68K_INS_FBSNE,
|
||||
M68K_INS_FBST,
|
||||
M68K_INS_FCMP,
|
||||
M68K_INS_FCOS,
|
||||
M68K_INS_FCOSH,
|
||||
M68K_INS_FDBF,
|
||||
M68K_INS_FDBEQ,
|
||||
M68K_INS_FDBOGT,
|
||||
M68K_INS_FDBOGE,
|
||||
M68K_INS_FDBOLT,
|
||||
M68K_INS_FDBOLE,
|
||||
M68K_INS_FDBOGL,
|
||||
M68K_INS_FDBOR,
|
||||
M68K_INS_FDBUN,
|
||||
M68K_INS_FDBUEQ,
|
||||
M68K_INS_FDBUGT,
|
||||
M68K_INS_FDBUGE,
|
||||
M68K_INS_FDBULT,
|
||||
M68K_INS_FDBULE,
|
||||
M68K_INS_FDBNE,
|
||||
M68K_INS_FDBT,
|
||||
M68K_INS_FDBSF,
|
||||
M68K_INS_FDBSEQ,
|
||||
M68K_INS_FDBGT,
|
||||
M68K_INS_FDBGE,
|
||||
M68K_INS_FDBLT,
|
||||
M68K_INS_FDBLE,
|
||||
M68K_INS_FDBGL,
|
||||
M68K_INS_FDBGLE,
|
||||
M68K_INS_FDBNGLE,
|
||||
M68K_INS_FDBNGL,
|
||||
M68K_INS_FDBNLE,
|
||||
M68K_INS_FDBNLT,
|
||||
M68K_INS_FDBNGE,
|
||||
M68K_INS_FDBNGT,
|
||||
M68K_INS_FDBSNE,
|
||||
M68K_INS_FDBST,
|
||||
M68K_INS_FDIV,
|
||||
M68K_INS_FSDIV,
|
||||
M68K_INS_FDDIV,
|
||||
M68K_INS_FETOX,
|
||||
M68K_INS_FETOXM1,
|
||||
M68K_INS_FGETEXP,
|
||||
M68K_INS_FGETMAN,
|
||||
M68K_INS_FINT,
|
||||
M68K_INS_FINTRZ,
|
||||
M68K_INS_FLOG10,
|
||||
M68K_INS_FLOG2,
|
||||
M68K_INS_FLOGN,
|
||||
M68K_INS_FLOGNP1,
|
||||
M68K_INS_FMOD,
|
||||
M68K_INS_FMOVE,
|
||||
M68K_INS_FSMOVE,
|
||||
M68K_INS_FDMOVE,
|
||||
M68K_INS_FMOVECR,
|
||||
M68K_INS_FMOVEM,
|
||||
M68K_INS_FMUL,
|
||||
M68K_INS_FSMUL,
|
||||
M68K_INS_FDMUL,
|
||||
M68K_INS_FNEG,
|
||||
M68K_INS_FSNEG,
|
||||
M68K_INS_FDNEG,
|
||||
M68K_INS_FNOP,
|
||||
M68K_INS_FREM,
|
||||
M68K_INS_FRESTORE,
|
||||
M68K_INS_FSAVE,
|
||||
M68K_INS_FSCALE,
|
||||
M68K_INS_FSGLDIV,
|
||||
M68K_INS_FSGLMUL,
|
||||
M68K_INS_FSIN,
|
||||
M68K_INS_FSINCOS,
|
||||
M68K_INS_FSINH,
|
||||
M68K_INS_FSQRT,
|
||||
M68K_INS_FSSQRT,
|
||||
M68K_INS_FDSQRT,
|
||||
M68K_INS_FSF,
|
||||
M68K_INS_FSBEQ,
|
||||
M68K_INS_FSOGT,
|
||||
M68K_INS_FSOGE,
|
||||
M68K_INS_FSOLT,
|
||||
M68K_INS_FSOLE,
|
||||
M68K_INS_FSOGL,
|
||||
M68K_INS_FSOR,
|
||||
M68K_INS_FSUN,
|
||||
M68K_INS_FSUEQ,
|
||||
M68K_INS_FSUGT,
|
||||
M68K_INS_FSUGE,
|
||||
M68K_INS_FSULT,
|
||||
M68K_INS_FSULE,
|
||||
M68K_INS_FSNE,
|
||||
M68K_INS_FST,
|
||||
M68K_INS_FSSF,
|
||||
M68K_INS_FSSEQ,
|
||||
M68K_INS_FSGT,
|
||||
M68K_INS_FSGE,
|
||||
M68K_INS_FSLT,
|
||||
M68K_INS_FSLE,
|
||||
M68K_INS_FSGL,
|
||||
M68K_INS_FSGLE,
|
||||
M68K_INS_FSNGLE,
|
||||
M68K_INS_FSNGL,
|
||||
M68K_INS_FSNLE,
|
||||
M68K_INS_FSNLT,
|
||||
M68K_INS_FSNGE,
|
||||
M68K_INS_FSNGT,
|
||||
M68K_INS_FSSNE,
|
||||
M68K_INS_FSST,
|
||||
M68K_INS_FSUB,
|
||||
M68K_INS_FSSUB,
|
||||
M68K_INS_FDSUB,
|
||||
M68K_INS_FTAN,
|
||||
M68K_INS_FTANH,
|
||||
M68K_INS_FTENTOX,
|
||||
M68K_INS_FTRAPF,
|
||||
M68K_INS_FTRAPEQ,
|
||||
M68K_INS_FTRAPOGT,
|
||||
M68K_INS_FTRAPOGE,
|
||||
M68K_INS_FTRAPOLT,
|
||||
M68K_INS_FTRAPOLE,
|
||||
M68K_INS_FTRAPOGL,
|
||||
M68K_INS_FTRAPOR,
|
||||
M68K_INS_FTRAPUN,
|
||||
M68K_INS_FTRAPUEQ,
|
||||
M68K_INS_FTRAPUGT,
|
||||
M68K_INS_FTRAPUGE,
|
||||
M68K_INS_FTRAPULT,
|
||||
M68K_INS_FTRAPULE,
|
||||
M68K_INS_FTRAPNE,
|
||||
M68K_INS_FTRAPT,
|
||||
M68K_INS_FTRAPSF,
|
||||
M68K_INS_FTRAPSEQ,
|
||||
M68K_INS_FTRAPGT,
|
||||
M68K_INS_FTRAPGE,
|
||||
M68K_INS_FTRAPLT,
|
||||
M68K_INS_FTRAPLE,
|
||||
M68K_INS_FTRAPGL,
|
||||
M68K_INS_FTRAPGLE,
|
||||
M68K_INS_FTRAPNGLE,
|
||||
M68K_INS_FTRAPNGL,
|
||||
M68K_INS_FTRAPNLE,
|
||||
M68K_INS_FTRAPNLT,
|
||||
M68K_INS_FTRAPNGE,
|
||||
M68K_INS_FTRAPNGT,
|
||||
M68K_INS_FTRAPSNE,
|
||||
M68K_INS_FTRAPST,
|
||||
M68K_INS_FTST,
|
||||
M68K_INS_FTWOTOX,
|
||||
M68K_INS_HALT,
|
||||
M68K_INS_ILLEGAL,
|
||||
M68K_INS_JMP,
|
||||
M68K_INS_JSR,
|
||||
M68K_INS_LEA,
|
||||
M68K_INS_LINK,
|
||||
M68K_INS_LPSTOP,
|
||||
M68K_INS_LSL,
|
||||
M68K_INS_LSR,
|
||||
M68K_INS_MOVE,
|
||||
M68K_INS_MOVEA,
|
||||
M68K_INS_MOVEC,
|
||||
M68K_INS_MOVEM,
|
||||
M68K_INS_MOVEP,
|
||||
M68K_INS_MOVEQ,
|
||||
M68K_INS_MOVES,
|
||||
M68K_INS_MOVE16,
|
||||
M68K_INS_MULS,
|
||||
M68K_INS_MULU,
|
||||
M68K_INS_NBCD,
|
||||
M68K_INS_NEG,
|
||||
M68K_INS_NEGX,
|
||||
M68K_INS_NOP,
|
||||
M68K_INS_NOT,
|
||||
M68K_INS_OR,
|
||||
M68K_INS_ORI,
|
||||
M68K_INS_PACK,
|
||||
M68K_INS_PEA,
|
||||
M68K_INS_PFLUSH,
|
||||
M68K_INS_PFLUSHA,
|
||||
M68K_INS_PFLUSHAN,
|
||||
M68K_INS_PFLUSHN,
|
||||
M68K_INS_PLOADR,
|
||||
M68K_INS_PLOADW,
|
||||
M68K_INS_PLPAR,
|
||||
M68K_INS_PLPAW,
|
||||
M68K_INS_PMOVE,
|
||||
M68K_INS_PMOVEFD,
|
||||
M68K_INS_PTESTR,
|
||||
M68K_INS_PTESTW,
|
||||
M68K_INS_PULSE,
|
||||
M68K_INS_REMS,
|
||||
M68K_INS_REMU,
|
||||
M68K_INS_RESET,
|
||||
M68K_INS_ROL,
|
||||
M68K_INS_ROR,
|
||||
M68K_INS_ROXL,
|
||||
M68K_INS_ROXR,
|
||||
M68K_INS_RTD,
|
||||
M68K_INS_RTE,
|
||||
M68K_INS_RTM,
|
||||
M68K_INS_RTR,
|
||||
M68K_INS_RTS,
|
||||
M68K_INS_SBCD,
|
||||
M68K_INS_ST,
|
||||
M68K_INS_SF,
|
||||
M68K_INS_SHI,
|
||||
M68K_INS_SLS,
|
||||
M68K_INS_SCC,
|
||||
M68K_INS_SHS,
|
||||
M68K_INS_SCS,
|
||||
M68K_INS_SLO,
|
||||
M68K_INS_SNE,
|
||||
M68K_INS_SEQ,
|
||||
M68K_INS_SVC,
|
||||
M68K_INS_SVS,
|
||||
M68K_INS_SPL,
|
||||
M68K_INS_SMI,
|
||||
M68K_INS_SGE,
|
||||
M68K_INS_SLT,
|
||||
M68K_INS_SGT,
|
||||
M68K_INS_SLE,
|
||||
M68K_INS_STOP,
|
||||
M68K_INS_SUB,
|
||||
M68K_INS_SUBA,
|
||||
M68K_INS_SUBI,
|
||||
M68K_INS_SUBQ,
|
||||
M68K_INS_SUBX,
|
||||
M68K_INS_SWAP,
|
||||
M68K_INS_TAS,
|
||||
M68K_INS_TRAP,
|
||||
M68K_INS_TRAPV,
|
||||
M68K_INS_TRAPT,
|
||||
M68K_INS_TRAPF,
|
||||
M68K_INS_TRAPHI,
|
||||
M68K_INS_TRAPLS,
|
||||
M68K_INS_TRAPCC,
|
||||
M68K_INS_TRAPHS,
|
||||
M68K_INS_TRAPCS,
|
||||
M68K_INS_TRAPLO,
|
||||
M68K_INS_TRAPNE,
|
||||
M68K_INS_TRAPEQ,
|
||||
M68K_INS_TRAPVC,
|
||||
M68K_INS_TRAPVS,
|
||||
M68K_INS_TRAPPL,
|
||||
M68K_INS_TRAPMI,
|
||||
M68K_INS_TRAPGE,
|
||||
M68K_INS_TRAPLT,
|
||||
M68K_INS_TRAPGT,
|
||||
M68K_INS_TRAPLE,
|
||||
M68K_INS_TST,
|
||||
M68K_INS_UNLK,
|
||||
M68K_INS_UNPK,
|
||||
M68K_INS_ENDING, // <-- mark the end of the list of instructions
|
||||
} m68k_insn;
|
||||
|
||||
/// Group of M68K instructions
|
||||
typedef enum m68k_group_type {
|
||||
M68K_GRP_INVALID = 0, ///< CS_GRUP_INVALID
|
||||
M68K_GRP_JUMP, ///< = CS_GRP_JUMP
|
||||
M68K_GRP_RET = 3, ///< = CS_GRP_RET
|
||||
M68K_GRP_IRET = 5, ///< = CS_GRP_IRET
|
||||
M68K_GRP_BRANCH_RELATIVE = 7, ///< = CS_GRP_BRANCH_RELATIVE
|
||||
|
||||
M68K_GRP_ENDING,// <-- mark the end of the list of groups
|
||||
} m68k_group_type;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,956 @@
|
||||
#ifndef CAPSTONE_MIPS_H
|
||||
#define CAPSTONE_MIPS_H
|
||||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
// GCC MIPS toolchain has a default macro called "mips" which breaks
|
||||
// compilation
|
||||
#undef mips
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
/// Operand type for instruction's operands
|
||||
typedef enum mips_op_type {
|
||||
MIPS_OP_INVALID = 0, ///< = CS_OP_INVALID (Uninitialized).
|
||||
MIPS_OP_REG, ///< = CS_OP_REG (Register operand).
|
||||
MIPS_OP_IMM, ///< = CS_OP_IMM (Immediate operand).
|
||||
MIPS_OP_MEM, ///< = CS_OP_MEM (Memory operand).
|
||||
} mips_op_type;
|
||||
|
||||
/// MIPS registers
|
||||
typedef enum mips_reg {
|
||||
MIPS_REG_INVALID = 0,
|
||||
// General purpose registers
|
||||
MIPS_REG_PC,
|
||||
|
||||
MIPS_REG_0,
|
||||
MIPS_REG_1,
|
||||
MIPS_REG_2,
|
||||
MIPS_REG_3,
|
||||
MIPS_REG_4,
|
||||
MIPS_REG_5,
|
||||
MIPS_REG_6,
|
||||
MIPS_REG_7,
|
||||
MIPS_REG_8,
|
||||
MIPS_REG_9,
|
||||
MIPS_REG_10,
|
||||
MIPS_REG_11,
|
||||
MIPS_REG_12,
|
||||
MIPS_REG_13,
|
||||
MIPS_REG_14,
|
||||
MIPS_REG_15,
|
||||
MIPS_REG_16,
|
||||
MIPS_REG_17,
|
||||
MIPS_REG_18,
|
||||
MIPS_REG_19,
|
||||
MIPS_REG_20,
|
||||
MIPS_REG_21,
|
||||
MIPS_REG_22,
|
||||
MIPS_REG_23,
|
||||
MIPS_REG_24,
|
||||
MIPS_REG_25,
|
||||
MIPS_REG_26,
|
||||
MIPS_REG_27,
|
||||
MIPS_REG_28,
|
||||
MIPS_REG_29,
|
||||
MIPS_REG_30,
|
||||
MIPS_REG_31,
|
||||
|
||||
// DSP registers
|
||||
MIPS_REG_DSPCCOND,
|
||||
MIPS_REG_DSPCARRY,
|
||||
MIPS_REG_DSPEFI,
|
||||
MIPS_REG_DSPOUTFLAG,
|
||||
MIPS_REG_DSPOUTFLAG16_19,
|
||||
MIPS_REG_DSPOUTFLAG20,
|
||||
MIPS_REG_DSPOUTFLAG21,
|
||||
MIPS_REG_DSPOUTFLAG22,
|
||||
MIPS_REG_DSPOUTFLAG23,
|
||||
MIPS_REG_DSPPOS,
|
||||
MIPS_REG_DSPSCOUNT,
|
||||
|
||||
// ACC registers
|
||||
MIPS_REG_AC0,
|
||||
MIPS_REG_AC1,
|
||||
MIPS_REG_AC2,
|
||||
MIPS_REG_AC3,
|
||||
|
||||
// COP registers
|
||||
MIPS_REG_CC0,
|
||||
MIPS_REG_CC1,
|
||||
MIPS_REG_CC2,
|
||||
MIPS_REG_CC3,
|
||||
MIPS_REG_CC4,
|
||||
MIPS_REG_CC5,
|
||||
MIPS_REG_CC6,
|
||||
MIPS_REG_CC7,
|
||||
|
||||
// FPU registers
|
||||
MIPS_REG_F0,
|
||||
MIPS_REG_F1,
|
||||
MIPS_REG_F2,
|
||||
MIPS_REG_F3,
|
||||
MIPS_REG_F4,
|
||||
MIPS_REG_F5,
|
||||
MIPS_REG_F6,
|
||||
MIPS_REG_F7,
|
||||
MIPS_REG_F8,
|
||||
MIPS_REG_F9,
|
||||
MIPS_REG_F10,
|
||||
MIPS_REG_F11,
|
||||
MIPS_REG_F12,
|
||||
MIPS_REG_F13,
|
||||
MIPS_REG_F14,
|
||||
MIPS_REG_F15,
|
||||
MIPS_REG_F16,
|
||||
MIPS_REG_F17,
|
||||
MIPS_REG_F18,
|
||||
MIPS_REG_F19,
|
||||
MIPS_REG_F20,
|
||||
MIPS_REG_F21,
|
||||
MIPS_REG_F22,
|
||||
MIPS_REG_F23,
|
||||
MIPS_REG_F24,
|
||||
MIPS_REG_F25,
|
||||
MIPS_REG_F26,
|
||||
MIPS_REG_F27,
|
||||
MIPS_REG_F28,
|
||||
MIPS_REG_F29,
|
||||
MIPS_REG_F30,
|
||||
MIPS_REG_F31,
|
||||
|
||||
MIPS_REG_FCC0,
|
||||
MIPS_REG_FCC1,
|
||||
MIPS_REG_FCC2,
|
||||
MIPS_REG_FCC3,
|
||||
MIPS_REG_FCC4,
|
||||
MIPS_REG_FCC5,
|
||||
MIPS_REG_FCC6,
|
||||
MIPS_REG_FCC7,
|
||||
|
||||
// AFPR128
|
||||
MIPS_REG_W0,
|
||||
MIPS_REG_W1,
|
||||
MIPS_REG_W2,
|
||||
MIPS_REG_W3,
|
||||
MIPS_REG_W4,
|
||||
MIPS_REG_W5,
|
||||
MIPS_REG_W6,
|
||||
MIPS_REG_W7,
|
||||
MIPS_REG_W8,
|
||||
MIPS_REG_W9,
|
||||
MIPS_REG_W10,
|
||||
MIPS_REG_W11,
|
||||
MIPS_REG_W12,
|
||||
MIPS_REG_W13,
|
||||
MIPS_REG_W14,
|
||||
MIPS_REG_W15,
|
||||
MIPS_REG_W16,
|
||||
MIPS_REG_W17,
|
||||
MIPS_REG_W18,
|
||||
MIPS_REG_W19,
|
||||
MIPS_REG_W20,
|
||||
MIPS_REG_W21,
|
||||
MIPS_REG_W22,
|
||||
MIPS_REG_W23,
|
||||
MIPS_REG_W24,
|
||||
MIPS_REG_W25,
|
||||
MIPS_REG_W26,
|
||||
MIPS_REG_W27,
|
||||
MIPS_REG_W28,
|
||||
MIPS_REG_W29,
|
||||
MIPS_REG_W30,
|
||||
MIPS_REG_W31,
|
||||
|
||||
MIPS_REG_HI,
|
||||
MIPS_REG_LO,
|
||||
|
||||
MIPS_REG_P0,
|
||||
MIPS_REG_P1,
|
||||
MIPS_REG_P2,
|
||||
|
||||
MIPS_REG_MPL0,
|
||||
MIPS_REG_MPL1,
|
||||
MIPS_REG_MPL2,
|
||||
|
||||
MIPS_REG_ENDING, // <-- mark the end of the list or registers
|
||||
|
||||
// alias registers
|
||||
MIPS_REG_ZERO = MIPS_REG_0,
|
||||
MIPS_REG_AT = MIPS_REG_1,
|
||||
MIPS_REG_V0 = MIPS_REG_2,
|
||||
MIPS_REG_V1 = MIPS_REG_3,
|
||||
MIPS_REG_A0 = MIPS_REG_4,
|
||||
MIPS_REG_A1 = MIPS_REG_5,
|
||||
MIPS_REG_A2 = MIPS_REG_6,
|
||||
MIPS_REG_A3 = MIPS_REG_7,
|
||||
MIPS_REG_T0 = MIPS_REG_8,
|
||||
MIPS_REG_T1 = MIPS_REG_9,
|
||||
MIPS_REG_T2 = MIPS_REG_10,
|
||||
MIPS_REG_T3 = MIPS_REG_11,
|
||||
MIPS_REG_T4 = MIPS_REG_12,
|
||||
MIPS_REG_T5 = MIPS_REG_13,
|
||||
MIPS_REG_T6 = MIPS_REG_14,
|
||||
MIPS_REG_T7 = MIPS_REG_15,
|
||||
MIPS_REG_S0 = MIPS_REG_16,
|
||||
MIPS_REG_S1 = MIPS_REG_17,
|
||||
MIPS_REG_S2 = MIPS_REG_18,
|
||||
MIPS_REG_S3 = MIPS_REG_19,
|
||||
MIPS_REG_S4 = MIPS_REG_20,
|
||||
MIPS_REG_S5 = MIPS_REG_21,
|
||||
MIPS_REG_S6 = MIPS_REG_22,
|
||||
MIPS_REG_S7 = MIPS_REG_23,
|
||||
MIPS_REG_T8 = MIPS_REG_24,
|
||||
MIPS_REG_T9 = MIPS_REG_25,
|
||||
MIPS_REG_K0 = MIPS_REG_26,
|
||||
MIPS_REG_K1 = MIPS_REG_27,
|
||||
MIPS_REG_GP = MIPS_REG_28,
|
||||
MIPS_REG_SP = MIPS_REG_29,
|
||||
MIPS_REG_FP = MIPS_REG_30, MIPS_REG_S8 = MIPS_REG_30,
|
||||
MIPS_REG_RA = MIPS_REG_31,
|
||||
|
||||
MIPS_REG_HI0 = MIPS_REG_AC0,
|
||||
MIPS_REG_HI1 = MIPS_REG_AC1,
|
||||
MIPS_REG_HI2 = MIPS_REG_AC2,
|
||||
MIPS_REG_HI3 = MIPS_REG_AC3,
|
||||
|
||||
MIPS_REG_LO0 = MIPS_REG_HI0,
|
||||
MIPS_REG_LO1 = MIPS_REG_HI1,
|
||||
MIPS_REG_LO2 = MIPS_REG_HI2,
|
||||
MIPS_REG_LO3 = MIPS_REG_HI3,
|
||||
} mips_reg;
|
||||
|
||||
/// Instruction's operand referring to memory
|
||||
/// This is associated with MIPS_OP_MEM operand type above
|
||||
typedef struct mips_op_mem {
|
||||
mips_reg base; ///< base register
|
||||
int64_t disp; ///< displacement/offset value
|
||||
} mips_op_mem;
|
||||
|
||||
/// Instruction operand
|
||||
typedef struct cs_mips_op {
|
||||
mips_op_type type; ///< operand type
|
||||
union {
|
||||
mips_reg reg; ///< register value for REG operand
|
||||
int64_t imm; ///< immediate value for IMM operand
|
||||
mips_op_mem mem; ///< base/index/scale/disp value for MEM operand
|
||||
};
|
||||
} cs_mips_op;
|
||||
|
||||
/// Instruction structure
|
||||
typedef struct cs_mips {
|
||||
/// Number of operands of this instruction,
|
||||
/// or 0 when instruction has no operand.
|
||||
uint8_t op_count;
|
||||
cs_mips_op operands[10]; ///< operands for this instruction.
|
||||
} cs_mips;
|
||||
|
||||
/// MIPS instruction
|
||||
typedef enum mips_insn {
|
||||
MIPS_INS_INVALID = 0,
|
||||
|
||||
MIPS_INS_ABSQ_S,
|
||||
MIPS_INS_ADD,
|
||||
MIPS_INS_ADDIUPC,
|
||||
MIPS_INS_ADDIUR1SP,
|
||||
MIPS_INS_ADDIUR2,
|
||||
MIPS_INS_ADDIUS5,
|
||||
MIPS_INS_ADDIUSP,
|
||||
MIPS_INS_ADDQH,
|
||||
MIPS_INS_ADDQH_R,
|
||||
MIPS_INS_ADDQ,
|
||||
MIPS_INS_ADDQ_S,
|
||||
MIPS_INS_ADDSC,
|
||||
MIPS_INS_ADDS_A,
|
||||
MIPS_INS_ADDS_S,
|
||||
MIPS_INS_ADDS_U,
|
||||
MIPS_INS_ADDU16,
|
||||
MIPS_INS_ADDUH,
|
||||
MIPS_INS_ADDUH_R,
|
||||
MIPS_INS_ADDU,
|
||||
MIPS_INS_ADDU_S,
|
||||
MIPS_INS_ADDVI,
|
||||
MIPS_INS_ADDV,
|
||||
MIPS_INS_ADDWC,
|
||||
MIPS_INS_ADD_A,
|
||||
MIPS_INS_ADDI,
|
||||
MIPS_INS_ADDIU,
|
||||
MIPS_INS_ALIGN,
|
||||
MIPS_INS_ALUIPC,
|
||||
MIPS_INS_AND,
|
||||
MIPS_INS_AND16,
|
||||
MIPS_INS_ANDI16,
|
||||
MIPS_INS_ANDI,
|
||||
MIPS_INS_APPEND,
|
||||
MIPS_INS_ASUB_S,
|
||||
MIPS_INS_ASUB_U,
|
||||
MIPS_INS_AUI,
|
||||
MIPS_INS_AUIPC,
|
||||
MIPS_INS_AVER_S,
|
||||
MIPS_INS_AVER_U,
|
||||
MIPS_INS_AVE_S,
|
||||
MIPS_INS_AVE_U,
|
||||
MIPS_INS_B16,
|
||||
MIPS_INS_BADDU,
|
||||
MIPS_INS_BAL,
|
||||
MIPS_INS_BALC,
|
||||
MIPS_INS_BALIGN,
|
||||
MIPS_INS_BBIT0,
|
||||
MIPS_INS_BBIT032,
|
||||
MIPS_INS_BBIT1,
|
||||
MIPS_INS_BBIT132,
|
||||
MIPS_INS_BC,
|
||||
MIPS_INS_BC0F,
|
||||
MIPS_INS_BC0FL,
|
||||
MIPS_INS_BC0T,
|
||||
MIPS_INS_BC0TL,
|
||||
MIPS_INS_BC1EQZ,
|
||||
MIPS_INS_BC1F,
|
||||
MIPS_INS_BC1FL,
|
||||
MIPS_INS_BC1NEZ,
|
||||
MIPS_INS_BC1T,
|
||||
MIPS_INS_BC1TL,
|
||||
MIPS_INS_BC2EQZ,
|
||||
MIPS_INS_BC2F,
|
||||
MIPS_INS_BC2FL,
|
||||
MIPS_INS_BC2NEZ,
|
||||
MIPS_INS_BC2T,
|
||||
MIPS_INS_BC2TL,
|
||||
MIPS_INS_BC3F,
|
||||
MIPS_INS_BC3FL,
|
||||
MIPS_INS_BC3T,
|
||||
MIPS_INS_BC3TL,
|
||||
MIPS_INS_BCLRI,
|
||||
MIPS_INS_BCLR,
|
||||
MIPS_INS_BEQ,
|
||||
MIPS_INS_BEQC,
|
||||
MIPS_INS_BEQL,
|
||||
MIPS_INS_BEQZ16,
|
||||
MIPS_INS_BEQZALC,
|
||||
MIPS_INS_BEQZC,
|
||||
MIPS_INS_BGEC,
|
||||
MIPS_INS_BGEUC,
|
||||
MIPS_INS_BGEZ,
|
||||
MIPS_INS_BGEZAL,
|
||||
MIPS_INS_BGEZALC,
|
||||
MIPS_INS_BGEZALL,
|
||||
MIPS_INS_BGEZALS,
|
||||
MIPS_INS_BGEZC,
|
||||
MIPS_INS_BGEZL,
|
||||
MIPS_INS_BGTZ,
|
||||
MIPS_INS_BGTZALC,
|
||||
MIPS_INS_BGTZC,
|
||||
MIPS_INS_BGTZL,
|
||||
MIPS_INS_BINSLI,
|
||||
MIPS_INS_BINSL,
|
||||
MIPS_INS_BINSRI,
|
||||
MIPS_INS_BINSR,
|
||||
MIPS_INS_BITREV,
|
||||
MIPS_INS_BITSWAP,
|
||||
MIPS_INS_BLEZ,
|
||||
MIPS_INS_BLEZALC,
|
||||
MIPS_INS_BLEZC,
|
||||
MIPS_INS_BLEZL,
|
||||
MIPS_INS_BLTC,
|
||||
MIPS_INS_BLTUC,
|
||||
MIPS_INS_BLTZ,
|
||||
MIPS_INS_BLTZAL,
|
||||
MIPS_INS_BLTZALC,
|
||||
MIPS_INS_BLTZALL,
|
||||
MIPS_INS_BLTZALS,
|
||||
MIPS_INS_BLTZC,
|
||||
MIPS_INS_BLTZL,
|
||||
MIPS_INS_BMNZI,
|
||||
MIPS_INS_BMNZ,
|
||||
MIPS_INS_BMZI,
|
||||
MIPS_INS_BMZ,
|
||||
MIPS_INS_BNE,
|
||||
MIPS_INS_BNEC,
|
||||
MIPS_INS_BNEGI,
|
||||
MIPS_INS_BNEG,
|
||||
MIPS_INS_BNEL,
|
||||
MIPS_INS_BNEZ16,
|
||||
MIPS_INS_BNEZALC,
|
||||
MIPS_INS_BNEZC,
|
||||
MIPS_INS_BNVC,
|
||||
MIPS_INS_BNZ,
|
||||
MIPS_INS_BOVC,
|
||||
MIPS_INS_BPOSGE32,
|
||||
MIPS_INS_BREAK,
|
||||
MIPS_INS_BREAK16,
|
||||
MIPS_INS_BSELI,
|
||||
MIPS_INS_BSEL,
|
||||
MIPS_INS_BSETI,
|
||||
MIPS_INS_BSET,
|
||||
MIPS_INS_BZ,
|
||||
MIPS_INS_BEQZ,
|
||||
MIPS_INS_B,
|
||||
MIPS_INS_BNEZ,
|
||||
MIPS_INS_BTEQZ,
|
||||
MIPS_INS_BTNEZ,
|
||||
MIPS_INS_CACHE,
|
||||
MIPS_INS_CEIL,
|
||||
MIPS_INS_CEQI,
|
||||
MIPS_INS_CEQ,
|
||||
MIPS_INS_CFC1,
|
||||
MIPS_INS_CFCMSA,
|
||||
MIPS_INS_CINS,
|
||||
MIPS_INS_CINS32,
|
||||
MIPS_INS_CLASS,
|
||||
MIPS_INS_CLEI_S,
|
||||
MIPS_INS_CLEI_U,
|
||||
MIPS_INS_CLE_S,
|
||||
MIPS_INS_CLE_U,
|
||||
MIPS_INS_CLO,
|
||||
MIPS_INS_CLTI_S,
|
||||
MIPS_INS_CLTI_U,
|
||||
MIPS_INS_CLT_S,
|
||||
MIPS_INS_CLT_U,
|
||||
MIPS_INS_CLZ,
|
||||
MIPS_INS_CMPGDU,
|
||||
MIPS_INS_CMPGU,
|
||||
MIPS_INS_CMPU,
|
||||
MIPS_INS_CMP,
|
||||
MIPS_INS_COPY_S,
|
||||
MIPS_INS_COPY_U,
|
||||
MIPS_INS_CTC1,
|
||||
MIPS_INS_CTCMSA,
|
||||
MIPS_INS_CVT,
|
||||
MIPS_INS_C,
|
||||
MIPS_INS_CMPI,
|
||||
MIPS_INS_DADD,
|
||||
MIPS_INS_DADDI,
|
||||
MIPS_INS_DADDIU,
|
||||
MIPS_INS_DADDU,
|
||||
MIPS_INS_DAHI,
|
||||
MIPS_INS_DALIGN,
|
||||
MIPS_INS_DATI,
|
||||
MIPS_INS_DAUI,
|
||||
MIPS_INS_DBITSWAP,
|
||||
MIPS_INS_DCLO,
|
||||
MIPS_INS_DCLZ,
|
||||
MIPS_INS_DDIV,
|
||||
MIPS_INS_DDIVU,
|
||||
MIPS_INS_DERET,
|
||||
MIPS_INS_DEXT,
|
||||
MIPS_INS_DEXTM,
|
||||
MIPS_INS_DEXTU,
|
||||
MIPS_INS_DI,
|
||||
MIPS_INS_DINS,
|
||||
MIPS_INS_DINSM,
|
||||
MIPS_INS_DINSU,
|
||||
MIPS_INS_DIV,
|
||||
MIPS_INS_DIVU,
|
||||
MIPS_INS_DIV_S,
|
||||
MIPS_INS_DIV_U,
|
||||
MIPS_INS_DLSA,
|
||||
MIPS_INS_DMFC0,
|
||||
MIPS_INS_DMFC1,
|
||||
MIPS_INS_DMFC2,
|
||||
MIPS_INS_DMOD,
|
||||
MIPS_INS_DMODU,
|
||||
MIPS_INS_DMTC0,
|
||||
MIPS_INS_DMTC1,
|
||||
MIPS_INS_DMTC2,
|
||||
MIPS_INS_DMUH,
|
||||
MIPS_INS_DMUHU,
|
||||
MIPS_INS_DMUL,
|
||||
MIPS_INS_DMULT,
|
||||
MIPS_INS_DMULTU,
|
||||
MIPS_INS_DMULU,
|
||||
MIPS_INS_DOTP_S,
|
||||
MIPS_INS_DOTP_U,
|
||||
MIPS_INS_DPADD_S,
|
||||
MIPS_INS_DPADD_U,
|
||||
MIPS_INS_DPAQX_SA,
|
||||
MIPS_INS_DPAQX_S,
|
||||
MIPS_INS_DPAQ_SA,
|
||||
MIPS_INS_DPAQ_S,
|
||||
MIPS_INS_DPAU,
|
||||
MIPS_INS_DPAX,
|
||||
MIPS_INS_DPA,
|
||||
MIPS_INS_DPOP,
|
||||
MIPS_INS_DPSQX_SA,
|
||||
MIPS_INS_DPSQX_S,
|
||||
MIPS_INS_DPSQ_SA,
|
||||
MIPS_INS_DPSQ_S,
|
||||
MIPS_INS_DPSUB_S,
|
||||
MIPS_INS_DPSUB_U,
|
||||
MIPS_INS_DPSU,
|
||||
MIPS_INS_DPSX,
|
||||
MIPS_INS_DPS,
|
||||
MIPS_INS_DROTR,
|
||||
MIPS_INS_DROTR32,
|
||||
MIPS_INS_DROTRV,
|
||||
MIPS_INS_DSBH,
|
||||
MIPS_INS_DSHD,
|
||||
MIPS_INS_DSLL,
|
||||
MIPS_INS_DSLL32,
|
||||
MIPS_INS_DSLLV,
|
||||
MIPS_INS_DSRA,
|
||||
MIPS_INS_DSRA32,
|
||||
MIPS_INS_DSRAV,
|
||||
MIPS_INS_DSRL,
|
||||
MIPS_INS_DSRL32,
|
||||
MIPS_INS_DSRLV,
|
||||
MIPS_INS_DSUB,
|
||||
MIPS_INS_DSUBU,
|
||||
MIPS_INS_EHB,
|
||||
MIPS_INS_EI,
|
||||
MIPS_INS_ERET,
|
||||
MIPS_INS_EXT,
|
||||
MIPS_INS_EXTP,
|
||||
MIPS_INS_EXTPDP,
|
||||
MIPS_INS_EXTPDPV,
|
||||
MIPS_INS_EXTPV,
|
||||
MIPS_INS_EXTRV_RS,
|
||||
MIPS_INS_EXTRV_R,
|
||||
MIPS_INS_EXTRV_S,
|
||||
MIPS_INS_EXTRV,
|
||||
MIPS_INS_EXTR_RS,
|
||||
MIPS_INS_EXTR_R,
|
||||
MIPS_INS_EXTR_S,
|
||||
MIPS_INS_EXTR,
|
||||
MIPS_INS_EXTS,
|
||||
MIPS_INS_EXTS32,
|
||||
MIPS_INS_ABS,
|
||||
MIPS_INS_FADD,
|
||||
MIPS_INS_FCAF,
|
||||
MIPS_INS_FCEQ,
|
||||
MIPS_INS_FCLASS,
|
||||
MIPS_INS_FCLE,
|
||||
MIPS_INS_FCLT,
|
||||
MIPS_INS_FCNE,
|
||||
MIPS_INS_FCOR,
|
||||
MIPS_INS_FCUEQ,
|
||||
MIPS_INS_FCULE,
|
||||
MIPS_INS_FCULT,
|
||||
MIPS_INS_FCUNE,
|
||||
MIPS_INS_FCUN,
|
||||
MIPS_INS_FDIV,
|
||||
MIPS_INS_FEXDO,
|
||||
MIPS_INS_FEXP2,
|
||||
MIPS_INS_FEXUPL,
|
||||
MIPS_INS_FEXUPR,
|
||||
MIPS_INS_FFINT_S,
|
||||
MIPS_INS_FFINT_U,
|
||||
MIPS_INS_FFQL,
|
||||
MIPS_INS_FFQR,
|
||||
MIPS_INS_FILL,
|
||||
MIPS_INS_FLOG2,
|
||||
MIPS_INS_FLOOR,
|
||||
MIPS_INS_FMADD,
|
||||
MIPS_INS_FMAX_A,
|
||||
MIPS_INS_FMAX,
|
||||
MIPS_INS_FMIN_A,
|
||||
MIPS_INS_FMIN,
|
||||
MIPS_INS_MOV,
|
||||
MIPS_INS_FMSUB,
|
||||
MIPS_INS_FMUL,
|
||||
MIPS_INS_MUL,
|
||||
MIPS_INS_NEG,
|
||||
MIPS_INS_FRCP,
|
||||
MIPS_INS_FRINT,
|
||||
MIPS_INS_FRSQRT,
|
||||
MIPS_INS_FSAF,
|
||||
MIPS_INS_FSEQ,
|
||||
MIPS_INS_FSLE,
|
||||
MIPS_INS_FSLT,
|
||||
MIPS_INS_FSNE,
|
||||
MIPS_INS_FSOR,
|
||||
MIPS_INS_FSQRT,
|
||||
MIPS_INS_SQRT,
|
||||
MIPS_INS_FSUB,
|
||||
MIPS_INS_SUB,
|
||||
MIPS_INS_FSUEQ,
|
||||
MIPS_INS_FSULE,
|
||||
MIPS_INS_FSULT,
|
||||
MIPS_INS_FSUNE,
|
||||
MIPS_INS_FSUN,
|
||||
MIPS_INS_FTINT_S,
|
||||
MIPS_INS_FTINT_U,
|
||||
MIPS_INS_FTQ,
|
||||
MIPS_INS_FTRUNC_S,
|
||||
MIPS_INS_FTRUNC_U,
|
||||
MIPS_INS_HADD_S,
|
||||
MIPS_INS_HADD_U,
|
||||
MIPS_INS_HSUB_S,
|
||||
MIPS_INS_HSUB_U,
|
||||
MIPS_INS_ILVEV,
|
||||
MIPS_INS_ILVL,
|
||||
MIPS_INS_ILVOD,
|
||||
MIPS_INS_ILVR,
|
||||
MIPS_INS_INS,
|
||||
MIPS_INS_INSERT,
|
||||
MIPS_INS_INSV,
|
||||
MIPS_INS_INSVE,
|
||||
MIPS_INS_J,
|
||||
MIPS_INS_JAL,
|
||||
MIPS_INS_JALR,
|
||||
MIPS_INS_JALRS16,
|
||||
MIPS_INS_JALRS,
|
||||
MIPS_INS_JALS,
|
||||
MIPS_INS_JALX,
|
||||
MIPS_INS_JIALC,
|
||||
MIPS_INS_JIC,
|
||||
MIPS_INS_JR,
|
||||
MIPS_INS_JR16,
|
||||
MIPS_INS_JRADDIUSP,
|
||||
MIPS_INS_JRC,
|
||||
MIPS_INS_JALRC,
|
||||
MIPS_INS_LB,
|
||||
MIPS_INS_LBU16,
|
||||
MIPS_INS_LBUX,
|
||||
MIPS_INS_LBU,
|
||||
MIPS_INS_LD,
|
||||
MIPS_INS_LDC1,
|
||||
MIPS_INS_LDC2,
|
||||
MIPS_INS_LDC3,
|
||||
MIPS_INS_LDI,
|
||||
MIPS_INS_LDL,
|
||||
MIPS_INS_LDPC,
|
||||
MIPS_INS_LDR,
|
||||
MIPS_INS_LDXC1,
|
||||
MIPS_INS_LH,
|
||||
MIPS_INS_LHU16,
|
||||
MIPS_INS_LHX,
|
||||
MIPS_INS_LHU,
|
||||
MIPS_INS_LI16,
|
||||
MIPS_INS_LL,
|
||||
MIPS_INS_LLD,
|
||||
MIPS_INS_LSA,
|
||||
MIPS_INS_LUXC1,
|
||||
MIPS_INS_LUI,
|
||||
MIPS_INS_LW,
|
||||
MIPS_INS_LW16,
|
||||
MIPS_INS_LWC1,
|
||||
MIPS_INS_LWC2,
|
||||
MIPS_INS_LWC3,
|
||||
MIPS_INS_LWL,
|
||||
MIPS_INS_LWM16,
|
||||
MIPS_INS_LWM32,
|
||||
MIPS_INS_LWPC,
|
||||
MIPS_INS_LWP,
|
||||
MIPS_INS_LWR,
|
||||
MIPS_INS_LWUPC,
|
||||
MIPS_INS_LWU,
|
||||
MIPS_INS_LWX,
|
||||
MIPS_INS_LWXC1,
|
||||
MIPS_INS_LWXS,
|
||||
MIPS_INS_LI,
|
||||
MIPS_INS_MADD,
|
||||
MIPS_INS_MADDF,
|
||||
MIPS_INS_MADDR_Q,
|
||||
MIPS_INS_MADDU,
|
||||
MIPS_INS_MADDV,
|
||||
MIPS_INS_MADD_Q,
|
||||
MIPS_INS_MAQ_SA,
|
||||
MIPS_INS_MAQ_S,
|
||||
MIPS_INS_MAXA,
|
||||
MIPS_INS_MAXI_S,
|
||||
MIPS_INS_MAXI_U,
|
||||
MIPS_INS_MAX_A,
|
||||
MIPS_INS_MAX,
|
||||
MIPS_INS_MAX_S,
|
||||
MIPS_INS_MAX_U,
|
||||
MIPS_INS_MFC0,
|
||||
MIPS_INS_MFC1,
|
||||
MIPS_INS_MFC2,
|
||||
MIPS_INS_MFHC1,
|
||||
MIPS_INS_MFHI,
|
||||
MIPS_INS_MFLO,
|
||||
MIPS_INS_MINA,
|
||||
MIPS_INS_MINI_S,
|
||||
MIPS_INS_MINI_U,
|
||||
MIPS_INS_MIN_A,
|
||||
MIPS_INS_MIN,
|
||||
MIPS_INS_MIN_S,
|
||||
MIPS_INS_MIN_U,
|
||||
MIPS_INS_MOD,
|
||||
MIPS_INS_MODSUB,
|
||||
MIPS_INS_MODU,
|
||||
MIPS_INS_MOD_S,
|
||||
MIPS_INS_MOD_U,
|
||||
MIPS_INS_MOVE,
|
||||
MIPS_INS_MOVEP,
|
||||
MIPS_INS_MOVF,
|
||||
MIPS_INS_MOVN,
|
||||
MIPS_INS_MOVT,
|
||||
MIPS_INS_MOVZ,
|
||||
MIPS_INS_MSUB,
|
||||
MIPS_INS_MSUBF,
|
||||
MIPS_INS_MSUBR_Q,
|
||||
MIPS_INS_MSUBU,
|
||||
MIPS_INS_MSUBV,
|
||||
MIPS_INS_MSUB_Q,
|
||||
MIPS_INS_MTC0,
|
||||
MIPS_INS_MTC1,
|
||||
MIPS_INS_MTC2,
|
||||
MIPS_INS_MTHC1,
|
||||
MIPS_INS_MTHI,
|
||||
MIPS_INS_MTHLIP,
|
||||
MIPS_INS_MTLO,
|
||||
MIPS_INS_MTM0,
|
||||
MIPS_INS_MTM1,
|
||||
MIPS_INS_MTM2,
|
||||
MIPS_INS_MTP0,
|
||||
MIPS_INS_MTP1,
|
||||
MIPS_INS_MTP2,
|
||||
MIPS_INS_MUH,
|
||||
MIPS_INS_MUHU,
|
||||
MIPS_INS_MULEQ_S,
|
||||
MIPS_INS_MULEU_S,
|
||||
MIPS_INS_MULQ_RS,
|
||||
MIPS_INS_MULQ_S,
|
||||
MIPS_INS_MULR_Q,
|
||||
MIPS_INS_MULSAQ_S,
|
||||
MIPS_INS_MULSA,
|
||||
MIPS_INS_MULT,
|
||||
MIPS_INS_MULTU,
|
||||
MIPS_INS_MULU,
|
||||
MIPS_INS_MULV,
|
||||
MIPS_INS_MUL_Q,
|
||||
MIPS_INS_MUL_S,
|
||||
MIPS_INS_NLOC,
|
||||
MIPS_INS_NLZC,
|
||||
MIPS_INS_NMADD,
|
||||
MIPS_INS_NMSUB,
|
||||
MIPS_INS_NOR,
|
||||
MIPS_INS_NORI,
|
||||
MIPS_INS_NOT16,
|
||||
MIPS_INS_NOT,
|
||||
MIPS_INS_OR,
|
||||
MIPS_INS_OR16,
|
||||
MIPS_INS_ORI,
|
||||
MIPS_INS_PACKRL,
|
||||
MIPS_INS_PAUSE,
|
||||
MIPS_INS_PCKEV,
|
||||
MIPS_INS_PCKOD,
|
||||
MIPS_INS_PCNT,
|
||||
MIPS_INS_PICK,
|
||||
MIPS_INS_POP,
|
||||
MIPS_INS_PRECEQU,
|
||||
MIPS_INS_PRECEQ,
|
||||
MIPS_INS_PRECEU,
|
||||
MIPS_INS_PRECRQU_S,
|
||||
MIPS_INS_PRECRQ,
|
||||
MIPS_INS_PRECRQ_RS,
|
||||
MIPS_INS_PRECR,
|
||||
MIPS_INS_PRECR_SRA,
|
||||
MIPS_INS_PRECR_SRA_R,
|
||||
MIPS_INS_PREF,
|
||||
MIPS_INS_PREPEND,
|
||||
MIPS_INS_RADDU,
|
||||
MIPS_INS_RDDSP,
|
||||
MIPS_INS_RDHWR,
|
||||
MIPS_INS_REPLV,
|
||||
MIPS_INS_REPL,
|
||||
MIPS_INS_RINT,
|
||||
MIPS_INS_ROTR,
|
||||
MIPS_INS_ROTRV,
|
||||
MIPS_INS_ROUND,
|
||||
MIPS_INS_SAT_S,
|
||||
MIPS_INS_SAT_U,
|
||||
MIPS_INS_SB,
|
||||
MIPS_INS_SB16,
|
||||
MIPS_INS_SC,
|
||||
MIPS_INS_SCD,
|
||||
MIPS_INS_SD,
|
||||
MIPS_INS_SDBBP,
|
||||
MIPS_INS_SDBBP16,
|
||||
MIPS_INS_SDC1,
|
||||
MIPS_INS_SDC2,
|
||||
MIPS_INS_SDC3,
|
||||
MIPS_INS_SDL,
|
||||
MIPS_INS_SDR,
|
||||
MIPS_INS_SDXC1,
|
||||
MIPS_INS_SEB,
|
||||
MIPS_INS_SEH,
|
||||
MIPS_INS_SELEQZ,
|
||||
MIPS_INS_SELNEZ,
|
||||
MIPS_INS_SEL,
|
||||
MIPS_INS_SEQ,
|
||||
MIPS_INS_SEQI,
|
||||
MIPS_INS_SH,
|
||||
MIPS_INS_SH16,
|
||||
MIPS_INS_SHF,
|
||||
MIPS_INS_SHILO,
|
||||
MIPS_INS_SHILOV,
|
||||
MIPS_INS_SHLLV,
|
||||
MIPS_INS_SHLLV_S,
|
||||
MIPS_INS_SHLL,
|
||||
MIPS_INS_SHLL_S,
|
||||
MIPS_INS_SHRAV,
|
||||
MIPS_INS_SHRAV_R,
|
||||
MIPS_INS_SHRA,
|
||||
MIPS_INS_SHRA_R,
|
||||
MIPS_INS_SHRLV,
|
||||
MIPS_INS_SHRL,
|
||||
MIPS_INS_SLDI,
|
||||
MIPS_INS_SLD,
|
||||
MIPS_INS_SLL,
|
||||
MIPS_INS_SLL16,
|
||||
MIPS_INS_SLLI,
|
||||
MIPS_INS_SLLV,
|
||||
MIPS_INS_SLT,
|
||||
MIPS_INS_SLTI,
|
||||
MIPS_INS_SLTIU,
|
||||
MIPS_INS_SLTU,
|
||||
MIPS_INS_SNE,
|
||||
MIPS_INS_SNEI,
|
||||
MIPS_INS_SPLATI,
|
||||
MIPS_INS_SPLAT,
|
||||
MIPS_INS_SRA,
|
||||
MIPS_INS_SRAI,
|
||||
MIPS_INS_SRARI,
|
||||
MIPS_INS_SRAR,
|
||||
MIPS_INS_SRAV,
|
||||
MIPS_INS_SRL,
|
||||
MIPS_INS_SRL16,
|
||||
MIPS_INS_SRLI,
|
||||
MIPS_INS_SRLRI,
|
||||
MIPS_INS_SRLR,
|
||||
MIPS_INS_SRLV,
|
||||
MIPS_INS_SSNOP,
|
||||
MIPS_INS_ST,
|
||||
MIPS_INS_SUBQH,
|
||||
MIPS_INS_SUBQH_R,
|
||||
MIPS_INS_SUBQ,
|
||||
MIPS_INS_SUBQ_S,
|
||||
MIPS_INS_SUBSUS_U,
|
||||
MIPS_INS_SUBSUU_S,
|
||||
MIPS_INS_SUBS_S,
|
||||
MIPS_INS_SUBS_U,
|
||||
MIPS_INS_SUBU16,
|
||||
MIPS_INS_SUBUH,
|
||||
MIPS_INS_SUBUH_R,
|
||||
MIPS_INS_SUBU,
|
||||
MIPS_INS_SUBU_S,
|
||||
MIPS_INS_SUBVI,
|
||||
MIPS_INS_SUBV,
|
||||
MIPS_INS_SUXC1,
|
||||
MIPS_INS_SW,
|
||||
MIPS_INS_SW16,
|
||||
MIPS_INS_SWC1,
|
||||
MIPS_INS_SWC2,
|
||||
MIPS_INS_SWC3,
|
||||
MIPS_INS_SWL,
|
||||
MIPS_INS_SWM16,
|
||||
MIPS_INS_SWM32,
|
||||
MIPS_INS_SWP,
|
||||
MIPS_INS_SWR,
|
||||
MIPS_INS_SWXC1,
|
||||
MIPS_INS_SYNC,
|
||||
MIPS_INS_SYNCI,
|
||||
MIPS_INS_SYSCALL,
|
||||
MIPS_INS_TEQ,
|
||||
MIPS_INS_TEQI,
|
||||
MIPS_INS_TGE,
|
||||
MIPS_INS_TGEI,
|
||||
MIPS_INS_TGEIU,
|
||||
MIPS_INS_TGEU,
|
||||
MIPS_INS_TLBP,
|
||||
MIPS_INS_TLBR,
|
||||
MIPS_INS_TLBWI,
|
||||
MIPS_INS_TLBWR,
|
||||
MIPS_INS_TLT,
|
||||
MIPS_INS_TLTI,
|
||||
MIPS_INS_TLTIU,
|
||||
MIPS_INS_TLTU,
|
||||
MIPS_INS_TNE,
|
||||
MIPS_INS_TNEI,
|
||||
MIPS_INS_TRUNC,
|
||||
MIPS_INS_V3MULU,
|
||||
MIPS_INS_VMM0,
|
||||
MIPS_INS_VMULU,
|
||||
MIPS_INS_VSHF,
|
||||
MIPS_INS_WAIT,
|
||||
MIPS_INS_WRDSP,
|
||||
MIPS_INS_WSBH,
|
||||
MIPS_INS_XOR,
|
||||
MIPS_INS_XOR16,
|
||||
MIPS_INS_XORI,
|
||||
|
||||
//> some alias instructions
|
||||
MIPS_INS_NOP,
|
||||
MIPS_INS_NEGU,
|
||||
|
||||
//> special instructions
|
||||
MIPS_INS_JALR_HB, // jump and link with Hazard Barrier
|
||||
MIPS_INS_JR_HB, // jump register with Hazard Barrier
|
||||
|
||||
MIPS_INS_ENDING,
|
||||
} mips_insn;
|
||||
|
||||
/// Group of MIPS instructions
|
||||
typedef enum mips_insn_group {
|
||||
MIPS_GRP_INVALID = 0, ///< = CS_GRP_INVALID
|
||||
|
||||
// Generic groups
|
||||
// all jump instructions (conditional+direct+indirect jumps)
|
||||
MIPS_GRP_JUMP, ///< = CS_GRP_JUMP
|
||||
// all call instructions
|
||||
MIPS_GRP_CALL, ///< = CS_GRP_CALL
|
||||
// all return instructions
|
||||
MIPS_GRP_RET, ///< = CS_GRP_RET
|
||||
// all interrupt instructions (int+syscall)
|
||||
MIPS_GRP_INT, ///< = CS_GRP_INT
|
||||
// all interrupt return instructions
|
||||
MIPS_GRP_IRET, ///< = CS_GRP_IRET
|
||||
// all privileged instructions
|
||||
MIPS_GRP_PRIVILEGE, ///< = CS_GRP_PRIVILEGE
|
||||
// all relative branching instructions
|
||||
MIPS_GRP_BRANCH_RELATIVE, ///< = CS_GRP_BRANCH_RELATIVE
|
||||
|
||||
// Architecture-specific groups
|
||||
MIPS_GRP_BITCOUNT = 128,
|
||||
MIPS_GRP_DSP,
|
||||
MIPS_GRP_DSPR2,
|
||||
MIPS_GRP_FPIDX,
|
||||
MIPS_GRP_MSA,
|
||||
MIPS_GRP_MIPS32R2,
|
||||
MIPS_GRP_MIPS64,
|
||||
MIPS_GRP_MIPS64R2,
|
||||
MIPS_GRP_SEINREG,
|
||||
MIPS_GRP_STDENC,
|
||||
MIPS_GRP_SWAP,
|
||||
MIPS_GRP_MICROMIPS,
|
||||
MIPS_GRP_MIPS16MODE,
|
||||
MIPS_GRP_FP64BIT,
|
||||
MIPS_GRP_NONANSFPMATH,
|
||||
MIPS_GRP_NOTFP64BIT,
|
||||
MIPS_GRP_NOTINMICROMIPS,
|
||||
MIPS_GRP_NOTNACL,
|
||||
MIPS_GRP_NOTMIPS32R6,
|
||||
MIPS_GRP_NOTMIPS64R6,
|
||||
MIPS_GRP_CNMIPS,
|
||||
MIPS_GRP_MIPS32,
|
||||
MIPS_GRP_MIPS32R6,
|
||||
MIPS_GRP_MIPS64R6,
|
||||
MIPS_GRP_MIPS2,
|
||||
MIPS_GRP_MIPS3,
|
||||
MIPS_GRP_MIPS3_32,
|
||||
MIPS_GRP_MIPS3_32R2,
|
||||
MIPS_GRP_MIPS4_32,
|
||||
MIPS_GRP_MIPS4_32R2,
|
||||
MIPS_GRP_MIPS5_32R2,
|
||||
MIPS_GRP_GP32BIT,
|
||||
MIPS_GRP_GP64BIT,
|
||||
|
||||
MIPS_GRP_ENDING,
|
||||
} mips_insn_group;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,122 @@
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Axel Souchet & Nguyen Anh Quynh, 2014 */
|
||||
|
||||
#ifndef CAPSTONE_PLATFORM_H
|
||||
#define CAPSTONE_PLATFORM_H
|
||||
|
||||
|
||||
// handle C99 issue (for pre-2013 VisualStudio)
|
||||
#if !defined(__CYGWIN__) && !defined(__MINGW32__) && !defined(__MINGW64__) && (defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64))
|
||||
// MSVC
|
||||
|
||||
// stdbool.h
|
||||
#if (_MSC_VER < 1800) || defined(_KERNEL_MODE)
|
||||
// this system does not have stdbool.h
|
||||
#ifndef __cplusplus
|
||||
typedef unsigned char bool;
|
||||
#define false 0
|
||||
#define true 1
|
||||
#endif // __cplusplus
|
||||
|
||||
#else
|
||||
// VisualStudio 2013+ -> C99 is supported
|
||||
#include <stdbool.h>
|
||||
#endif // (_MSC_VER < 1800) || defined(_KERNEL_MODE)
|
||||
|
||||
#else
|
||||
// not MSVC -> C99 is supported
|
||||
#include <stdbool.h>
|
||||
#endif // !defined(__CYGWIN__) && !defined(__MINGW32__) && !defined(__MINGW64__) && (defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64))
|
||||
|
||||
|
||||
// handle inttypes.h / stdint.h compatibility
|
||||
#if defined(_WIN32_WCE) && (_WIN32_WCE < 0x800)
|
||||
#include "windowsce/stdint.h"
|
||||
#endif // defined(_WIN32_WCE) && (_WIN32_WCE < 0x800)
|
||||
|
||||
#if defined(CAPSTONE_HAS_OSXKERNEL) || (defined(_MSC_VER) && (_MSC_VER <= 1700 || defined(_KERNEL_MODE)))
|
||||
// this system does not have inttypes.h
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER <= 1600 || defined(_KERNEL_MODE))
|
||||
// this system does not have stdint.h
|
||||
typedef signed char int8_t;
|
||||
typedef signed short int16_t;
|
||||
typedef signed int int32_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef signed long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER <= 1600 || defined(_KERNEL_MODE))
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1600 || defined(_KERNEL_MODE))
|
||||
#define INT8_MIN (-127i8 - 1)
|
||||
#define INT16_MIN (-32767i16 - 1)
|
||||
#define INT32_MIN (-2147483647i32 - 1)
|
||||
#define INT64_MIN (-9223372036854775807i64 - 1)
|
||||
#define INT8_MAX 127i8
|
||||
#define INT16_MAX 32767i16
|
||||
#define INT32_MAX 2147483647i32
|
||||
#define INT64_MAX 9223372036854775807i64
|
||||
#define UINT8_MAX 0xffui8
|
||||
#define UINT16_MAX 0xffffui16
|
||||
#define UINT32_MAX 0xffffffffui32
|
||||
#define UINT64_MAX 0xffffffffffffffffui64
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER < 1600 || defined(_KERNEL_MODE))
|
||||
|
||||
#ifdef CAPSTONE_HAS_OSXKERNEL
|
||||
// this system has stdint.h
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#define __PRI_8_LENGTH_MODIFIER__ "hh"
|
||||
#define __PRI_64_LENGTH_MODIFIER__ "ll"
|
||||
|
||||
#define PRId8 __PRI_8_LENGTH_MODIFIER__ "d"
|
||||
#define PRIi8 __PRI_8_LENGTH_MODIFIER__ "i"
|
||||
#define PRIo8 __PRI_8_LENGTH_MODIFIER__ "o"
|
||||
#define PRIu8 __PRI_8_LENGTH_MODIFIER__ "u"
|
||||
#define PRIx8 __PRI_8_LENGTH_MODIFIER__ "x"
|
||||
#define PRIX8 __PRI_8_LENGTH_MODIFIER__ "X"
|
||||
|
||||
#define PRId16 "hd"
|
||||
#define PRIi16 "hi"
|
||||
#define PRIo16 "ho"
|
||||
#define PRIu16 "hu"
|
||||
#define PRIx16 "hx"
|
||||
#define PRIX16 "hX"
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1700
|
||||
#define PRId32 "ld"
|
||||
#define PRIi32 "li"
|
||||
#define PRIo32 "lo"
|
||||
#define PRIu32 "lu"
|
||||
#define PRIx32 "lx"
|
||||
#define PRIX32 "lX"
|
||||
#else // OSX
|
||||
#define PRId32 "d"
|
||||
#define PRIi32 "i"
|
||||
#define PRIo32 "o"
|
||||
#define PRIu32 "u"
|
||||
#define PRIx32 "x"
|
||||
#define PRIX32 "X"
|
||||
#endif // defined(_MSC_VER) && _MSC_VER <= 1700
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1700
|
||||
// redefine functions from inttypes.h used in cstool
|
||||
#define strtoull _strtoui64
|
||||
#endif
|
||||
|
||||
#define PRId64 __PRI_64_LENGTH_MODIFIER__ "d"
|
||||
#define PRIi64 __PRI_64_LENGTH_MODIFIER__ "i"
|
||||
#define PRIo64 __PRI_64_LENGTH_MODIFIER__ "o"
|
||||
#define PRIu64 __PRI_64_LENGTH_MODIFIER__ "u"
|
||||
#define PRIx64 __PRI_64_LENGTH_MODIFIER__ "x"
|
||||
#define PRIX64 __PRI_64_LENGTH_MODIFIER__ "X"
|
||||
|
||||
#else
|
||||
// this system has inttypes.h by default
|
||||
#include <inttypes.h>
|
||||
#endif // defined(CAPSTONE_HAS_OSXKERNEL) || (defined(_MSC_VER) && (_MSC_VER <= 1700 || defined(_KERNEL_MODE)))
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,520 @@
|
||||
#ifndef CAPSTONE_SPARC_H
|
||||
#define CAPSTONE_SPARC_H
|
||||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2014-2015 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
// GCC SPARC toolchain has a default macro called "sparc" which breaks
|
||||
// compilation
|
||||
#undef sparc
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
/// Enums corresponding to Sparc condition codes, both icc's and fcc's.
|
||||
typedef enum sparc_cc {
|
||||
SPARC_CC_INVALID = 0, ///< invalid CC (default)
|
||||
// Integer condition codes
|
||||
SPARC_CC_ICC_A = 8+256, ///< Always
|
||||
SPARC_CC_ICC_N = 0+256, ///< Never
|
||||
SPARC_CC_ICC_NE = 9+256, ///< Not Equal
|
||||
SPARC_CC_ICC_E = 1+256, ///< Equal
|
||||
SPARC_CC_ICC_G = 10+256, ///< Greater
|
||||
SPARC_CC_ICC_LE = 2+256, ///< Less or Equal
|
||||
SPARC_CC_ICC_GE = 11+256, ///< Greater or Equal
|
||||
SPARC_CC_ICC_L = 3+256, ///< Less
|
||||
SPARC_CC_ICC_GU = 12+256, ///< Greater Unsigned
|
||||
SPARC_CC_ICC_LEU = 4+256, ///< Less or Equal Unsigned
|
||||
SPARC_CC_ICC_CC = 13+256, ///< Carry Clear/Great or Equal Unsigned
|
||||
SPARC_CC_ICC_CS = 5+256, ///< Carry Set/Less Unsigned
|
||||
SPARC_CC_ICC_POS = 14+256, ///< Positive
|
||||
SPARC_CC_ICC_NEG = 6+256, ///< Negative
|
||||
SPARC_CC_ICC_VC = 15+256, ///< Overflow Clear
|
||||
SPARC_CC_ICC_VS = 7+256, ///< Overflow Set
|
||||
|
||||
// Floating condition codes
|
||||
SPARC_CC_FCC_A = 8+16+256, ///< Always
|
||||
SPARC_CC_FCC_N = 0+16+256, ///< Never
|
||||
SPARC_CC_FCC_U = 7+16+256, ///< Unordered
|
||||
SPARC_CC_FCC_G = 6+16+256, ///< Greater
|
||||
SPARC_CC_FCC_UG = 5+16+256, ///< Unordered or Greater
|
||||
SPARC_CC_FCC_L = 4+16+256, ///< Less
|
||||
SPARC_CC_FCC_UL = 3+16+256, ///< Unordered or Less
|
||||
SPARC_CC_FCC_LG = 2+16+256, ///< Less or Greater
|
||||
SPARC_CC_FCC_NE = 1+16+256, ///< Not Equal
|
||||
SPARC_CC_FCC_E = 9+16+256, ///< Equal
|
||||
SPARC_CC_FCC_UE = 10+16+256, ///< Unordered or Equal
|
||||
SPARC_CC_FCC_GE = 11+16+256, ///< Greater or Equal
|
||||
SPARC_CC_FCC_UGE = 12+16+256, ///< Unordered or Greater or Equal
|
||||
SPARC_CC_FCC_LE = 13+16+256, ///< Less or Equal
|
||||
SPARC_CC_FCC_ULE = 14+16+256, ///< Unordered or Less or Equal
|
||||
SPARC_CC_FCC_O = 15+16+256, ///< Ordered
|
||||
} sparc_cc;
|
||||
|
||||
/// Branch hint
|
||||
typedef enum sparc_hint {
|
||||
SPARC_HINT_INVALID = 0, ///< no hint
|
||||
SPARC_HINT_A = 1 << 0, ///< annul delay slot instruction
|
||||
SPARC_HINT_PT = 1 << 1, ///< branch taken
|
||||
SPARC_HINT_PN = 1 << 2, ///< branch NOT taken
|
||||
} sparc_hint;
|
||||
|
||||
/// Operand type for instruction's operands
|
||||
typedef enum sparc_op_type {
|
||||
SPARC_OP_INVALID = 0, ///< = CS_OP_INVALID (Uninitialized).
|
||||
SPARC_OP_REG, ///< = CS_OP_REG (Register operand).
|
||||
SPARC_OP_IMM, ///< = CS_OP_IMM (Immediate operand).
|
||||
SPARC_OP_MEM, ///< = CS_OP_MEM (Memory operand).
|
||||
} sparc_op_type;
|
||||
|
||||
/// SPARC registers
|
||||
typedef enum sparc_reg {
|
||||
SPARC_REG_INVALID = 0,
|
||||
|
||||
SPARC_REG_F0,
|
||||
SPARC_REG_F1,
|
||||
SPARC_REG_F2,
|
||||
SPARC_REG_F3,
|
||||
SPARC_REG_F4,
|
||||
SPARC_REG_F5,
|
||||
SPARC_REG_F6,
|
||||
SPARC_REG_F7,
|
||||
SPARC_REG_F8,
|
||||
SPARC_REG_F9,
|
||||
SPARC_REG_F10,
|
||||
SPARC_REG_F11,
|
||||
SPARC_REG_F12,
|
||||
SPARC_REG_F13,
|
||||
SPARC_REG_F14,
|
||||
SPARC_REG_F15,
|
||||
SPARC_REG_F16,
|
||||
SPARC_REG_F17,
|
||||
SPARC_REG_F18,
|
||||
SPARC_REG_F19,
|
||||
SPARC_REG_F20,
|
||||
SPARC_REG_F21,
|
||||
SPARC_REG_F22,
|
||||
SPARC_REG_F23,
|
||||
SPARC_REG_F24,
|
||||
SPARC_REG_F25,
|
||||
SPARC_REG_F26,
|
||||
SPARC_REG_F27,
|
||||
SPARC_REG_F28,
|
||||
SPARC_REG_F29,
|
||||
SPARC_REG_F30,
|
||||
SPARC_REG_F31,
|
||||
SPARC_REG_F32,
|
||||
SPARC_REG_F34,
|
||||
SPARC_REG_F36,
|
||||
SPARC_REG_F38,
|
||||
SPARC_REG_F40,
|
||||
SPARC_REG_F42,
|
||||
SPARC_REG_F44,
|
||||
SPARC_REG_F46,
|
||||
SPARC_REG_F48,
|
||||
SPARC_REG_F50,
|
||||
SPARC_REG_F52,
|
||||
SPARC_REG_F54,
|
||||
SPARC_REG_F56,
|
||||
SPARC_REG_F58,
|
||||
SPARC_REG_F60,
|
||||
SPARC_REG_F62,
|
||||
SPARC_REG_FCC0, // Floating condition codes
|
||||
SPARC_REG_FCC1,
|
||||
SPARC_REG_FCC2,
|
||||
SPARC_REG_FCC3,
|
||||
SPARC_REG_FP,
|
||||
SPARC_REG_G0,
|
||||
SPARC_REG_G1,
|
||||
SPARC_REG_G2,
|
||||
SPARC_REG_G3,
|
||||
SPARC_REG_G4,
|
||||
SPARC_REG_G5,
|
||||
SPARC_REG_G6,
|
||||
SPARC_REG_G7,
|
||||
SPARC_REG_I0,
|
||||
SPARC_REG_I1,
|
||||
SPARC_REG_I2,
|
||||
SPARC_REG_I3,
|
||||
SPARC_REG_I4,
|
||||
SPARC_REG_I5,
|
||||
SPARC_REG_I7,
|
||||
SPARC_REG_ICC, // Integer condition codes
|
||||
SPARC_REG_L0,
|
||||
SPARC_REG_L1,
|
||||
SPARC_REG_L2,
|
||||
SPARC_REG_L3,
|
||||
SPARC_REG_L4,
|
||||
SPARC_REG_L5,
|
||||
SPARC_REG_L6,
|
||||
SPARC_REG_L7,
|
||||
SPARC_REG_O0,
|
||||
SPARC_REG_O1,
|
||||
SPARC_REG_O2,
|
||||
SPARC_REG_O3,
|
||||
SPARC_REG_O4,
|
||||
SPARC_REG_O5,
|
||||
SPARC_REG_O7,
|
||||
SPARC_REG_SP,
|
||||
SPARC_REG_Y,
|
||||
|
||||
// special register
|
||||
SPARC_REG_XCC,
|
||||
|
||||
SPARC_REG_ENDING, // <-- mark the end of the list of registers
|
||||
|
||||
// extras
|
||||
SPARC_REG_O6 = SPARC_REG_SP,
|
||||
SPARC_REG_I6 = SPARC_REG_FP,
|
||||
} sparc_reg;
|
||||
|
||||
/// Instruction's operand referring to memory
|
||||
/// This is associated with SPARC_OP_MEM operand type above
|
||||
typedef struct sparc_op_mem {
|
||||
uint8_t base; ///< base register, can be safely interpreted as
|
||||
///< a value of type `sparc_reg`, but it is only
|
||||
///< one byte wide
|
||||
uint8_t index; ///< index register, same conditions apply here
|
||||
int32_t disp; ///< displacement/offset value
|
||||
} sparc_op_mem;
|
||||
|
||||
/// Instruction operand
|
||||
typedef struct cs_sparc_op {
|
||||
sparc_op_type type; ///< operand type
|
||||
union {
|
||||
sparc_reg reg; ///< register value for REG operand
|
||||
int64_t imm; ///< immediate value for IMM operand
|
||||
sparc_op_mem mem; ///< base/disp value for MEM operand
|
||||
};
|
||||
} cs_sparc_op;
|
||||
|
||||
/// Instruction structure
|
||||
typedef struct cs_sparc {
|
||||
sparc_cc cc; ///< code condition for this insn
|
||||
sparc_hint hint; ///< branch hint: encoding as bitwise OR of sparc_hint.
|
||||
/// Number of operands of this instruction,
|
||||
/// or 0 when instruction has no operand.
|
||||
uint8_t op_count;
|
||||
cs_sparc_op operands[4]; ///< operands for this instruction.
|
||||
} cs_sparc;
|
||||
|
||||
/// SPARC instruction
|
||||
typedef enum sparc_insn {
|
||||
SPARC_INS_INVALID = 0,
|
||||
|
||||
SPARC_INS_ADDCC,
|
||||
SPARC_INS_ADDX,
|
||||
SPARC_INS_ADDXCC,
|
||||
SPARC_INS_ADDXC,
|
||||
SPARC_INS_ADDXCCC,
|
||||
SPARC_INS_ADD,
|
||||
SPARC_INS_ALIGNADDR,
|
||||
SPARC_INS_ALIGNADDRL,
|
||||
SPARC_INS_ANDCC,
|
||||
SPARC_INS_ANDNCC,
|
||||
SPARC_INS_ANDN,
|
||||
SPARC_INS_AND,
|
||||
SPARC_INS_ARRAY16,
|
||||
SPARC_INS_ARRAY32,
|
||||
SPARC_INS_ARRAY8,
|
||||
SPARC_INS_B,
|
||||
SPARC_INS_JMP,
|
||||
SPARC_INS_BMASK,
|
||||
SPARC_INS_FB,
|
||||
SPARC_INS_BRGEZ,
|
||||
SPARC_INS_BRGZ,
|
||||
SPARC_INS_BRLEZ,
|
||||
SPARC_INS_BRLZ,
|
||||
SPARC_INS_BRNZ,
|
||||
SPARC_INS_BRZ,
|
||||
SPARC_INS_BSHUFFLE,
|
||||
SPARC_INS_CALL,
|
||||
SPARC_INS_CASX,
|
||||
SPARC_INS_CAS,
|
||||
SPARC_INS_CMASK16,
|
||||
SPARC_INS_CMASK32,
|
||||
SPARC_INS_CMASK8,
|
||||
SPARC_INS_CMP,
|
||||
SPARC_INS_EDGE16,
|
||||
SPARC_INS_EDGE16L,
|
||||
SPARC_INS_EDGE16LN,
|
||||
SPARC_INS_EDGE16N,
|
||||
SPARC_INS_EDGE32,
|
||||
SPARC_INS_EDGE32L,
|
||||
SPARC_INS_EDGE32LN,
|
||||
SPARC_INS_EDGE32N,
|
||||
SPARC_INS_EDGE8,
|
||||
SPARC_INS_EDGE8L,
|
||||
SPARC_INS_EDGE8LN,
|
||||
SPARC_INS_EDGE8N,
|
||||
SPARC_INS_FABSD,
|
||||
SPARC_INS_FABSQ,
|
||||
SPARC_INS_FABSS,
|
||||
SPARC_INS_FADDD,
|
||||
SPARC_INS_FADDQ,
|
||||
SPARC_INS_FADDS,
|
||||
SPARC_INS_FALIGNDATA,
|
||||
SPARC_INS_FAND,
|
||||
SPARC_INS_FANDNOT1,
|
||||
SPARC_INS_FANDNOT1S,
|
||||
SPARC_INS_FANDNOT2,
|
||||
SPARC_INS_FANDNOT2S,
|
||||
SPARC_INS_FANDS,
|
||||
SPARC_INS_FCHKSM16,
|
||||
SPARC_INS_FCMPD,
|
||||
SPARC_INS_FCMPEQ16,
|
||||
SPARC_INS_FCMPEQ32,
|
||||
SPARC_INS_FCMPGT16,
|
||||
SPARC_INS_FCMPGT32,
|
||||
SPARC_INS_FCMPLE16,
|
||||
SPARC_INS_FCMPLE32,
|
||||
SPARC_INS_FCMPNE16,
|
||||
SPARC_INS_FCMPNE32,
|
||||
SPARC_INS_FCMPQ,
|
||||
SPARC_INS_FCMPS,
|
||||
SPARC_INS_FDIVD,
|
||||
SPARC_INS_FDIVQ,
|
||||
SPARC_INS_FDIVS,
|
||||
SPARC_INS_FDMULQ,
|
||||
SPARC_INS_FDTOI,
|
||||
SPARC_INS_FDTOQ,
|
||||
SPARC_INS_FDTOS,
|
||||
SPARC_INS_FDTOX,
|
||||
SPARC_INS_FEXPAND,
|
||||
SPARC_INS_FHADDD,
|
||||
SPARC_INS_FHADDS,
|
||||
SPARC_INS_FHSUBD,
|
||||
SPARC_INS_FHSUBS,
|
||||
SPARC_INS_FITOD,
|
||||
SPARC_INS_FITOQ,
|
||||
SPARC_INS_FITOS,
|
||||
SPARC_INS_FLCMPD,
|
||||
SPARC_INS_FLCMPS,
|
||||
SPARC_INS_FLUSHW,
|
||||
SPARC_INS_FMEAN16,
|
||||
SPARC_INS_FMOVD,
|
||||
SPARC_INS_FMOVQ,
|
||||
SPARC_INS_FMOVRDGEZ,
|
||||
SPARC_INS_FMOVRQGEZ,
|
||||
SPARC_INS_FMOVRSGEZ,
|
||||
SPARC_INS_FMOVRDGZ,
|
||||
SPARC_INS_FMOVRQGZ,
|
||||
SPARC_INS_FMOVRSGZ,
|
||||
SPARC_INS_FMOVRDLEZ,
|
||||
SPARC_INS_FMOVRQLEZ,
|
||||
SPARC_INS_FMOVRSLEZ,
|
||||
SPARC_INS_FMOVRDLZ,
|
||||
SPARC_INS_FMOVRQLZ,
|
||||
SPARC_INS_FMOVRSLZ,
|
||||
SPARC_INS_FMOVRDNZ,
|
||||
SPARC_INS_FMOVRQNZ,
|
||||
SPARC_INS_FMOVRSNZ,
|
||||
SPARC_INS_FMOVRDZ,
|
||||
SPARC_INS_FMOVRQZ,
|
||||
SPARC_INS_FMOVRSZ,
|
||||
SPARC_INS_FMOVS,
|
||||
SPARC_INS_FMUL8SUX16,
|
||||
SPARC_INS_FMUL8ULX16,
|
||||
SPARC_INS_FMUL8X16,
|
||||
SPARC_INS_FMUL8X16AL,
|
||||
SPARC_INS_FMUL8X16AU,
|
||||
SPARC_INS_FMULD,
|
||||
SPARC_INS_FMULD8SUX16,
|
||||
SPARC_INS_FMULD8ULX16,
|
||||
SPARC_INS_FMULQ,
|
||||
SPARC_INS_FMULS,
|
||||
SPARC_INS_FNADDD,
|
||||
SPARC_INS_FNADDS,
|
||||
SPARC_INS_FNAND,
|
||||
SPARC_INS_FNANDS,
|
||||
SPARC_INS_FNEGD,
|
||||
SPARC_INS_FNEGQ,
|
||||
SPARC_INS_FNEGS,
|
||||
SPARC_INS_FNHADDD,
|
||||
SPARC_INS_FNHADDS,
|
||||
SPARC_INS_FNOR,
|
||||
SPARC_INS_FNORS,
|
||||
SPARC_INS_FNOT1,
|
||||
SPARC_INS_FNOT1S,
|
||||
SPARC_INS_FNOT2,
|
||||
SPARC_INS_FNOT2S,
|
||||
SPARC_INS_FONE,
|
||||
SPARC_INS_FONES,
|
||||
SPARC_INS_FOR,
|
||||
SPARC_INS_FORNOT1,
|
||||
SPARC_INS_FORNOT1S,
|
||||
SPARC_INS_FORNOT2,
|
||||
SPARC_INS_FORNOT2S,
|
||||
SPARC_INS_FORS,
|
||||
SPARC_INS_FPACK16,
|
||||
SPARC_INS_FPACK32,
|
||||
SPARC_INS_FPACKFIX,
|
||||
SPARC_INS_FPADD16,
|
||||
SPARC_INS_FPADD16S,
|
||||
SPARC_INS_FPADD32,
|
||||
SPARC_INS_FPADD32S,
|
||||
SPARC_INS_FPADD64,
|
||||
SPARC_INS_FPMERGE,
|
||||
SPARC_INS_FPSUB16,
|
||||
SPARC_INS_FPSUB16S,
|
||||
SPARC_INS_FPSUB32,
|
||||
SPARC_INS_FPSUB32S,
|
||||
SPARC_INS_FQTOD,
|
||||
SPARC_INS_FQTOI,
|
||||
SPARC_INS_FQTOS,
|
||||
SPARC_INS_FQTOX,
|
||||
SPARC_INS_FSLAS16,
|
||||
SPARC_INS_FSLAS32,
|
||||
SPARC_INS_FSLL16,
|
||||
SPARC_INS_FSLL32,
|
||||
SPARC_INS_FSMULD,
|
||||
SPARC_INS_FSQRTD,
|
||||
SPARC_INS_FSQRTQ,
|
||||
SPARC_INS_FSQRTS,
|
||||
SPARC_INS_FSRA16,
|
||||
SPARC_INS_FSRA32,
|
||||
SPARC_INS_FSRC1,
|
||||
SPARC_INS_FSRC1S,
|
||||
SPARC_INS_FSRC2,
|
||||
SPARC_INS_FSRC2S,
|
||||
SPARC_INS_FSRL16,
|
||||
SPARC_INS_FSRL32,
|
||||
SPARC_INS_FSTOD,
|
||||
SPARC_INS_FSTOI,
|
||||
SPARC_INS_FSTOQ,
|
||||
SPARC_INS_FSTOX,
|
||||
SPARC_INS_FSUBD,
|
||||
SPARC_INS_FSUBQ,
|
||||
SPARC_INS_FSUBS,
|
||||
SPARC_INS_FXNOR,
|
||||
SPARC_INS_FXNORS,
|
||||
SPARC_INS_FXOR,
|
||||
SPARC_INS_FXORS,
|
||||
SPARC_INS_FXTOD,
|
||||
SPARC_INS_FXTOQ,
|
||||
SPARC_INS_FXTOS,
|
||||
SPARC_INS_FZERO,
|
||||
SPARC_INS_FZEROS,
|
||||
SPARC_INS_JMPL,
|
||||
SPARC_INS_LDD,
|
||||
SPARC_INS_LD,
|
||||
SPARC_INS_LDQ,
|
||||
SPARC_INS_LDSB,
|
||||
SPARC_INS_LDSH,
|
||||
SPARC_INS_LDSW,
|
||||
SPARC_INS_LDUB,
|
||||
SPARC_INS_LDUH,
|
||||
SPARC_INS_LDX,
|
||||
SPARC_INS_LZCNT,
|
||||
SPARC_INS_MEMBAR,
|
||||
SPARC_INS_MOVDTOX,
|
||||
SPARC_INS_MOV,
|
||||
SPARC_INS_MOVRGEZ,
|
||||
SPARC_INS_MOVRGZ,
|
||||
SPARC_INS_MOVRLEZ,
|
||||
SPARC_INS_MOVRLZ,
|
||||
SPARC_INS_MOVRNZ,
|
||||
SPARC_INS_MOVRZ,
|
||||
SPARC_INS_MOVSTOSW,
|
||||
SPARC_INS_MOVSTOUW,
|
||||
SPARC_INS_MULX,
|
||||
SPARC_INS_NOP,
|
||||
SPARC_INS_ORCC,
|
||||
SPARC_INS_ORNCC,
|
||||
SPARC_INS_ORN,
|
||||
SPARC_INS_OR,
|
||||
SPARC_INS_PDIST,
|
||||
SPARC_INS_PDISTN,
|
||||
SPARC_INS_POPC,
|
||||
SPARC_INS_RD,
|
||||
SPARC_INS_RESTORE,
|
||||
SPARC_INS_RETT,
|
||||
SPARC_INS_SAVE,
|
||||
SPARC_INS_SDIVCC,
|
||||
SPARC_INS_SDIVX,
|
||||
SPARC_INS_SDIV,
|
||||
SPARC_INS_SETHI,
|
||||
SPARC_INS_SHUTDOWN,
|
||||
SPARC_INS_SIAM,
|
||||
SPARC_INS_SLLX,
|
||||
SPARC_INS_SLL,
|
||||
SPARC_INS_SMULCC,
|
||||
SPARC_INS_SMUL,
|
||||
SPARC_INS_SRAX,
|
||||
SPARC_INS_SRA,
|
||||
SPARC_INS_SRLX,
|
||||
SPARC_INS_SRL,
|
||||
SPARC_INS_STBAR,
|
||||
SPARC_INS_STB,
|
||||
SPARC_INS_STD,
|
||||
SPARC_INS_ST,
|
||||
SPARC_INS_STH,
|
||||
SPARC_INS_STQ,
|
||||
SPARC_INS_STX,
|
||||
SPARC_INS_SUBCC,
|
||||
SPARC_INS_SUBX,
|
||||
SPARC_INS_SUBXCC,
|
||||
SPARC_INS_SUB,
|
||||
SPARC_INS_SWAP,
|
||||
SPARC_INS_TADDCCTV,
|
||||
SPARC_INS_TADDCC,
|
||||
SPARC_INS_T,
|
||||
SPARC_INS_TSUBCCTV,
|
||||
SPARC_INS_TSUBCC,
|
||||
SPARC_INS_UDIVCC,
|
||||
SPARC_INS_UDIVX,
|
||||
SPARC_INS_UDIV,
|
||||
SPARC_INS_UMULCC,
|
||||
SPARC_INS_UMULXHI,
|
||||
SPARC_INS_UMUL,
|
||||
SPARC_INS_UNIMP,
|
||||
SPARC_INS_FCMPED,
|
||||
SPARC_INS_FCMPEQ,
|
||||
SPARC_INS_FCMPES,
|
||||
SPARC_INS_WR,
|
||||
SPARC_INS_XMULX,
|
||||
SPARC_INS_XMULXHI,
|
||||
SPARC_INS_XNORCC,
|
||||
SPARC_INS_XNOR,
|
||||
SPARC_INS_XORCC,
|
||||
SPARC_INS_XOR,
|
||||
|
||||
// alias instructions
|
||||
SPARC_INS_RET,
|
||||
SPARC_INS_RETL,
|
||||
|
||||
SPARC_INS_ENDING, // <-- mark the end of the list of instructions
|
||||
} sparc_insn;
|
||||
|
||||
/// Group of SPARC instructions
|
||||
typedef enum sparc_insn_group {
|
||||
SPARC_GRP_INVALID = 0, ///< = CS_GRP_INVALID
|
||||
|
||||
// Generic groups
|
||||
// all jump instructions (conditional+direct+indirect jumps)
|
||||
SPARC_GRP_JUMP, ///< = CS_GRP_JUMP
|
||||
|
||||
// Architecture-specific groups
|
||||
SPARC_GRP_HARDQUAD = 128,
|
||||
SPARC_GRP_V9,
|
||||
SPARC_GRP_VIS,
|
||||
SPARC_GRP_VIS2,
|
||||
SPARC_GRP_VIS3,
|
||||
SPARC_GRP_32BIT,
|
||||
SPARC_GRP_64BIT,
|
||||
|
||||
SPARC_GRP_ENDING, // <-- mark the end of the list of groups
|
||||
} sparc_insn_group;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,830 @@
|
||||
#ifndef CAPSTONE_SYSTEMZ_H
|
||||
#define CAPSTONE_SYSTEMZ_H
|
||||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2014-2015 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
/// Enums corresponding to SystemZ condition codes
|
||||
typedef enum sysz_cc {
|
||||
SYSZ_CC_INVALID = 0, ///< invalid CC (default)
|
||||
|
||||
SYSZ_CC_O,
|
||||
SYSZ_CC_H,
|
||||
SYSZ_CC_NLE,
|
||||
SYSZ_CC_L,
|
||||
SYSZ_CC_NHE,
|
||||
SYSZ_CC_LH,
|
||||
SYSZ_CC_NE,
|
||||
SYSZ_CC_E,
|
||||
SYSZ_CC_NLH,
|
||||
SYSZ_CC_HE,
|
||||
SYSZ_CC_NL,
|
||||
SYSZ_CC_LE,
|
||||
SYSZ_CC_NH,
|
||||
SYSZ_CC_NO,
|
||||
} sysz_cc;
|
||||
|
||||
/// Operand type for instruction's operands
|
||||
typedef enum sysz_op_type {
|
||||
SYSZ_OP_INVALID = 0, ///< = CS_OP_INVALID (Uninitialized).
|
||||
SYSZ_OP_REG, ///< = CS_OP_REG (Register operand).
|
||||
SYSZ_OP_IMM, ///< = CS_OP_IMM (Immediate operand).
|
||||
SYSZ_OP_MEM, ///< = CS_OP_MEM (Memory operand).
|
||||
SYSZ_OP_ACREG = 64, ///< Access register operand.
|
||||
} sysz_op_type;
|
||||
|
||||
/// SystemZ registers
|
||||
typedef enum sysz_reg {
|
||||
SYSZ_REG_INVALID = 0,
|
||||
|
||||
SYSZ_REG_0,
|
||||
SYSZ_REG_1,
|
||||
SYSZ_REG_2,
|
||||
SYSZ_REG_3,
|
||||
SYSZ_REG_4,
|
||||
SYSZ_REG_5,
|
||||
SYSZ_REG_6,
|
||||
SYSZ_REG_7,
|
||||
SYSZ_REG_8,
|
||||
SYSZ_REG_9,
|
||||
SYSZ_REG_10,
|
||||
SYSZ_REG_11,
|
||||
SYSZ_REG_12,
|
||||
SYSZ_REG_13,
|
||||
SYSZ_REG_14,
|
||||
SYSZ_REG_15,
|
||||
SYSZ_REG_CC,
|
||||
SYSZ_REG_F0,
|
||||
SYSZ_REG_F1,
|
||||
SYSZ_REG_F2,
|
||||
SYSZ_REG_F3,
|
||||
SYSZ_REG_F4,
|
||||
SYSZ_REG_F5,
|
||||
SYSZ_REG_F6,
|
||||
SYSZ_REG_F7,
|
||||
SYSZ_REG_F8,
|
||||
SYSZ_REG_F9,
|
||||
SYSZ_REG_F10,
|
||||
SYSZ_REG_F11,
|
||||
SYSZ_REG_F12,
|
||||
SYSZ_REG_F13,
|
||||
SYSZ_REG_F14,
|
||||
SYSZ_REG_F15,
|
||||
|
||||
SYSZ_REG_R0L,
|
||||
|
||||
SYSZ_REG_ENDING,
|
||||
} sysz_reg;
|
||||
|
||||
/// Instruction's operand referring to memory
|
||||
/// This is associated with SYSZ_OP_MEM operand type above
|
||||
typedef struct sysz_op_mem {
|
||||
uint8_t base; ///< base register, can be safely interpreted as
|
||||
///< a value of type `sysz_reg`, but it is only
|
||||
///< one byte wide
|
||||
uint8_t index; ///< index register, same conditions apply here
|
||||
uint64_t length; ///< BDLAddr operand
|
||||
int64_t disp; ///< displacement/offset value
|
||||
} sysz_op_mem;
|
||||
|
||||
/// Instruction operand
|
||||
typedef struct cs_sysz_op {
|
||||
sysz_op_type type; ///< operand type
|
||||
union {
|
||||
sysz_reg reg; ///< register value for REG operand
|
||||
int64_t imm; ///< immediate value for IMM operand
|
||||
sysz_op_mem mem; ///< base/disp value for MEM operand
|
||||
};
|
||||
} cs_sysz_op;
|
||||
|
||||
// Instruction structure
|
||||
typedef struct cs_sysz {
|
||||
sysz_cc cc; ///< Code condition
|
||||
/// Number of operands of this instruction,
|
||||
/// or 0 when instruction has no operand.
|
||||
uint8_t op_count;
|
||||
cs_sysz_op operands[6]; ///< operands for this instruction.
|
||||
} cs_sysz;
|
||||
|
||||
/// SystemZ instruction
|
||||
typedef enum sysz_insn {
|
||||
SYSZ_INS_INVALID = 0,
|
||||
|
||||
SYSZ_INS_A,
|
||||
SYSZ_INS_ADB,
|
||||
SYSZ_INS_ADBR,
|
||||
SYSZ_INS_AEB,
|
||||
SYSZ_INS_AEBR,
|
||||
SYSZ_INS_AFI,
|
||||
SYSZ_INS_AG,
|
||||
SYSZ_INS_AGF,
|
||||
SYSZ_INS_AGFI,
|
||||
SYSZ_INS_AGFR,
|
||||
SYSZ_INS_AGHI,
|
||||
SYSZ_INS_AGHIK,
|
||||
SYSZ_INS_AGR,
|
||||
SYSZ_INS_AGRK,
|
||||
SYSZ_INS_AGSI,
|
||||
SYSZ_INS_AH,
|
||||
SYSZ_INS_AHI,
|
||||
SYSZ_INS_AHIK,
|
||||
SYSZ_INS_AHY,
|
||||
SYSZ_INS_AIH,
|
||||
SYSZ_INS_AL,
|
||||
SYSZ_INS_ALC,
|
||||
SYSZ_INS_ALCG,
|
||||
SYSZ_INS_ALCGR,
|
||||
SYSZ_INS_ALCR,
|
||||
SYSZ_INS_ALFI,
|
||||
SYSZ_INS_ALG,
|
||||
SYSZ_INS_ALGF,
|
||||
SYSZ_INS_ALGFI,
|
||||
SYSZ_INS_ALGFR,
|
||||
SYSZ_INS_ALGHSIK,
|
||||
SYSZ_INS_ALGR,
|
||||
SYSZ_INS_ALGRK,
|
||||
SYSZ_INS_ALHSIK,
|
||||
SYSZ_INS_ALR,
|
||||
SYSZ_INS_ALRK,
|
||||
SYSZ_INS_ALY,
|
||||
SYSZ_INS_AR,
|
||||
SYSZ_INS_ARK,
|
||||
SYSZ_INS_ASI,
|
||||
SYSZ_INS_AXBR,
|
||||
SYSZ_INS_AY,
|
||||
SYSZ_INS_BCR,
|
||||
SYSZ_INS_BRC,
|
||||
SYSZ_INS_BRCL,
|
||||
SYSZ_INS_CGIJ,
|
||||
SYSZ_INS_CGRJ,
|
||||
SYSZ_INS_CIJ,
|
||||
SYSZ_INS_CLGIJ,
|
||||
SYSZ_INS_CLGRJ,
|
||||
SYSZ_INS_CLIJ,
|
||||
SYSZ_INS_CLRJ,
|
||||
SYSZ_INS_CRJ,
|
||||
SYSZ_INS_BER,
|
||||
SYSZ_INS_JE,
|
||||
SYSZ_INS_JGE,
|
||||
SYSZ_INS_LOCE,
|
||||
SYSZ_INS_LOCGE,
|
||||
SYSZ_INS_LOCGRE,
|
||||
SYSZ_INS_LOCRE,
|
||||
SYSZ_INS_STOCE,
|
||||
SYSZ_INS_STOCGE,
|
||||
SYSZ_INS_BHR,
|
||||
SYSZ_INS_BHER,
|
||||
SYSZ_INS_JHE,
|
||||
SYSZ_INS_JGHE,
|
||||
SYSZ_INS_LOCHE,
|
||||
SYSZ_INS_LOCGHE,
|
||||
SYSZ_INS_LOCGRHE,
|
||||
SYSZ_INS_LOCRHE,
|
||||
SYSZ_INS_STOCHE,
|
||||
SYSZ_INS_STOCGHE,
|
||||
SYSZ_INS_JH,
|
||||
SYSZ_INS_JGH,
|
||||
SYSZ_INS_LOCH,
|
||||
SYSZ_INS_LOCGH,
|
||||
SYSZ_INS_LOCGRH,
|
||||
SYSZ_INS_LOCRH,
|
||||
SYSZ_INS_STOCH,
|
||||
SYSZ_INS_STOCGH,
|
||||
SYSZ_INS_CGIJNLH,
|
||||
SYSZ_INS_CGRJNLH,
|
||||
SYSZ_INS_CIJNLH,
|
||||
SYSZ_INS_CLGIJNLH,
|
||||
SYSZ_INS_CLGRJNLH,
|
||||
SYSZ_INS_CLIJNLH,
|
||||
SYSZ_INS_CLRJNLH,
|
||||
SYSZ_INS_CRJNLH,
|
||||
SYSZ_INS_CGIJE,
|
||||
SYSZ_INS_CGRJE,
|
||||
SYSZ_INS_CIJE,
|
||||
SYSZ_INS_CLGIJE,
|
||||
SYSZ_INS_CLGRJE,
|
||||
SYSZ_INS_CLIJE,
|
||||
SYSZ_INS_CLRJE,
|
||||
SYSZ_INS_CRJE,
|
||||
SYSZ_INS_CGIJNLE,
|
||||
SYSZ_INS_CGRJNLE,
|
||||
SYSZ_INS_CIJNLE,
|
||||
SYSZ_INS_CLGIJNLE,
|
||||
SYSZ_INS_CLGRJNLE,
|
||||
SYSZ_INS_CLIJNLE,
|
||||
SYSZ_INS_CLRJNLE,
|
||||
SYSZ_INS_CRJNLE,
|
||||
SYSZ_INS_CGIJH,
|
||||
SYSZ_INS_CGRJH,
|
||||
SYSZ_INS_CIJH,
|
||||
SYSZ_INS_CLGIJH,
|
||||
SYSZ_INS_CLGRJH,
|
||||
SYSZ_INS_CLIJH,
|
||||
SYSZ_INS_CLRJH,
|
||||
SYSZ_INS_CRJH,
|
||||
SYSZ_INS_CGIJNL,
|
||||
SYSZ_INS_CGRJNL,
|
||||
SYSZ_INS_CIJNL,
|
||||
SYSZ_INS_CLGIJNL,
|
||||
SYSZ_INS_CLGRJNL,
|
||||
SYSZ_INS_CLIJNL,
|
||||
SYSZ_INS_CLRJNL,
|
||||
SYSZ_INS_CRJNL,
|
||||
SYSZ_INS_CGIJHE,
|
||||
SYSZ_INS_CGRJHE,
|
||||
SYSZ_INS_CIJHE,
|
||||
SYSZ_INS_CLGIJHE,
|
||||
SYSZ_INS_CLGRJHE,
|
||||
SYSZ_INS_CLIJHE,
|
||||
SYSZ_INS_CLRJHE,
|
||||
SYSZ_INS_CRJHE,
|
||||
SYSZ_INS_CGIJNHE,
|
||||
SYSZ_INS_CGRJNHE,
|
||||
SYSZ_INS_CIJNHE,
|
||||
SYSZ_INS_CLGIJNHE,
|
||||
SYSZ_INS_CLGRJNHE,
|
||||
SYSZ_INS_CLIJNHE,
|
||||
SYSZ_INS_CLRJNHE,
|
||||
SYSZ_INS_CRJNHE,
|
||||
SYSZ_INS_CGIJL,
|
||||
SYSZ_INS_CGRJL,
|
||||
SYSZ_INS_CIJL,
|
||||
SYSZ_INS_CLGIJL,
|
||||
SYSZ_INS_CLGRJL,
|
||||
SYSZ_INS_CLIJL,
|
||||
SYSZ_INS_CLRJL,
|
||||
SYSZ_INS_CRJL,
|
||||
SYSZ_INS_CGIJNH,
|
||||
SYSZ_INS_CGRJNH,
|
||||
SYSZ_INS_CIJNH,
|
||||
SYSZ_INS_CLGIJNH,
|
||||
SYSZ_INS_CLGRJNH,
|
||||
SYSZ_INS_CLIJNH,
|
||||
SYSZ_INS_CLRJNH,
|
||||
SYSZ_INS_CRJNH,
|
||||
SYSZ_INS_CGIJLE,
|
||||
SYSZ_INS_CGRJLE,
|
||||
SYSZ_INS_CIJLE,
|
||||
SYSZ_INS_CLGIJLE,
|
||||
SYSZ_INS_CLGRJLE,
|
||||
SYSZ_INS_CLIJLE,
|
||||
SYSZ_INS_CLRJLE,
|
||||
SYSZ_INS_CRJLE,
|
||||
SYSZ_INS_CGIJNE,
|
||||
SYSZ_INS_CGRJNE,
|
||||
SYSZ_INS_CIJNE,
|
||||
SYSZ_INS_CLGIJNE,
|
||||
SYSZ_INS_CLGRJNE,
|
||||
SYSZ_INS_CLIJNE,
|
||||
SYSZ_INS_CLRJNE,
|
||||
SYSZ_INS_CRJNE,
|
||||
SYSZ_INS_CGIJLH,
|
||||
SYSZ_INS_CGRJLH,
|
||||
SYSZ_INS_CIJLH,
|
||||
SYSZ_INS_CLGIJLH,
|
||||
SYSZ_INS_CLGRJLH,
|
||||
SYSZ_INS_CLIJLH,
|
||||
SYSZ_INS_CLRJLH,
|
||||
SYSZ_INS_CRJLH,
|
||||
SYSZ_INS_BLR,
|
||||
SYSZ_INS_BLER,
|
||||
SYSZ_INS_JLE,
|
||||
SYSZ_INS_JGLE,
|
||||
SYSZ_INS_LOCLE,
|
||||
SYSZ_INS_LOCGLE,
|
||||
SYSZ_INS_LOCGRLE,
|
||||
SYSZ_INS_LOCRLE,
|
||||
SYSZ_INS_STOCLE,
|
||||
SYSZ_INS_STOCGLE,
|
||||
SYSZ_INS_BLHR,
|
||||
SYSZ_INS_JLH,
|
||||
SYSZ_INS_JGLH,
|
||||
SYSZ_INS_LOCLH,
|
||||
SYSZ_INS_LOCGLH,
|
||||
SYSZ_INS_LOCGRLH,
|
||||
SYSZ_INS_LOCRLH,
|
||||
SYSZ_INS_STOCLH,
|
||||
SYSZ_INS_STOCGLH,
|
||||
SYSZ_INS_JL,
|
||||
SYSZ_INS_JGL,
|
||||
SYSZ_INS_LOCL,
|
||||
SYSZ_INS_LOCGL,
|
||||
SYSZ_INS_LOCGRL,
|
||||
SYSZ_INS_LOCRL,
|
||||
SYSZ_INS_LOC,
|
||||
SYSZ_INS_LOCG,
|
||||
SYSZ_INS_LOCGR,
|
||||
SYSZ_INS_LOCR,
|
||||
SYSZ_INS_STOCL,
|
||||
SYSZ_INS_STOCGL,
|
||||
SYSZ_INS_BNER,
|
||||
SYSZ_INS_JNE,
|
||||
SYSZ_INS_JGNE,
|
||||
SYSZ_INS_LOCNE,
|
||||
SYSZ_INS_LOCGNE,
|
||||
SYSZ_INS_LOCGRNE,
|
||||
SYSZ_INS_LOCRNE,
|
||||
SYSZ_INS_STOCNE,
|
||||
SYSZ_INS_STOCGNE,
|
||||
SYSZ_INS_BNHR,
|
||||
SYSZ_INS_BNHER,
|
||||
SYSZ_INS_JNHE,
|
||||
SYSZ_INS_JGNHE,
|
||||
SYSZ_INS_LOCNHE,
|
||||
SYSZ_INS_LOCGNHE,
|
||||
SYSZ_INS_LOCGRNHE,
|
||||
SYSZ_INS_LOCRNHE,
|
||||
SYSZ_INS_STOCNHE,
|
||||
SYSZ_INS_STOCGNHE,
|
||||
SYSZ_INS_JNH,
|
||||
SYSZ_INS_JGNH,
|
||||
SYSZ_INS_LOCNH,
|
||||
SYSZ_INS_LOCGNH,
|
||||
SYSZ_INS_LOCGRNH,
|
||||
SYSZ_INS_LOCRNH,
|
||||
SYSZ_INS_STOCNH,
|
||||
SYSZ_INS_STOCGNH,
|
||||
SYSZ_INS_BNLR,
|
||||
SYSZ_INS_BNLER,
|
||||
SYSZ_INS_JNLE,
|
||||
SYSZ_INS_JGNLE,
|
||||
SYSZ_INS_LOCNLE,
|
||||
SYSZ_INS_LOCGNLE,
|
||||
SYSZ_INS_LOCGRNLE,
|
||||
SYSZ_INS_LOCRNLE,
|
||||
SYSZ_INS_STOCNLE,
|
||||
SYSZ_INS_STOCGNLE,
|
||||
SYSZ_INS_BNLHR,
|
||||
SYSZ_INS_JNLH,
|
||||
SYSZ_INS_JGNLH,
|
||||
SYSZ_INS_LOCNLH,
|
||||
SYSZ_INS_LOCGNLH,
|
||||
SYSZ_INS_LOCGRNLH,
|
||||
SYSZ_INS_LOCRNLH,
|
||||
SYSZ_INS_STOCNLH,
|
||||
SYSZ_INS_STOCGNLH,
|
||||
SYSZ_INS_JNL,
|
||||
SYSZ_INS_JGNL,
|
||||
SYSZ_INS_LOCNL,
|
||||
SYSZ_INS_LOCGNL,
|
||||
SYSZ_INS_LOCGRNL,
|
||||
SYSZ_INS_LOCRNL,
|
||||
SYSZ_INS_STOCNL,
|
||||
SYSZ_INS_STOCGNL,
|
||||
SYSZ_INS_BNOR,
|
||||
SYSZ_INS_JNO,
|
||||
SYSZ_INS_JGNO,
|
||||
SYSZ_INS_LOCNO,
|
||||
SYSZ_INS_LOCGNO,
|
||||
SYSZ_INS_LOCGRNO,
|
||||
SYSZ_INS_LOCRNO,
|
||||
SYSZ_INS_STOCNO,
|
||||
SYSZ_INS_STOCGNO,
|
||||
SYSZ_INS_BOR,
|
||||
SYSZ_INS_JO,
|
||||
SYSZ_INS_JGO,
|
||||
SYSZ_INS_LOCO,
|
||||
SYSZ_INS_LOCGO,
|
||||
SYSZ_INS_LOCGRO,
|
||||
SYSZ_INS_LOCRO,
|
||||
SYSZ_INS_STOCO,
|
||||
SYSZ_INS_STOCGO,
|
||||
SYSZ_INS_STOC,
|
||||
SYSZ_INS_STOCG,
|
||||
SYSZ_INS_BASR,
|
||||
SYSZ_INS_BR,
|
||||
SYSZ_INS_BRAS,
|
||||
SYSZ_INS_BRASL,
|
||||
SYSZ_INS_J,
|
||||
SYSZ_INS_JG,
|
||||
SYSZ_INS_BRCT,
|
||||
SYSZ_INS_BRCTG,
|
||||
SYSZ_INS_C,
|
||||
SYSZ_INS_CDB,
|
||||
SYSZ_INS_CDBR,
|
||||
SYSZ_INS_CDFBR,
|
||||
SYSZ_INS_CDGBR,
|
||||
SYSZ_INS_CDLFBR,
|
||||
SYSZ_INS_CDLGBR,
|
||||
SYSZ_INS_CEB,
|
||||
SYSZ_INS_CEBR,
|
||||
SYSZ_INS_CEFBR,
|
||||
SYSZ_INS_CEGBR,
|
||||
SYSZ_INS_CELFBR,
|
||||
SYSZ_INS_CELGBR,
|
||||
SYSZ_INS_CFDBR,
|
||||
SYSZ_INS_CFEBR,
|
||||
SYSZ_INS_CFI,
|
||||
SYSZ_INS_CFXBR,
|
||||
SYSZ_INS_CG,
|
||||
SYSZ_INS_CGDBR,
|
||||
SYSZ_INS_CGEBR,
|
||||
SYSZ_INS_CGF,
|
||||
SYSZ_INS_CGFI,
|
||||
SYSZ_INS_CGFR,
|
||||
SYSZ_INS_CGFRL,
|
||||
SYSZ_INS_CGH,
|
||||
SYSZ_INS_CGHI,
|
||||
SYSZ_INS_CGHRL,
|
||||
SYSZ_INS_CGHSI,
|
||||
SYSZ_INS_CGR,
|
||||
SYSZ_INS_CGRL,
|
||||
SYSZ_INS_CGXBR,
|
||||
SYSZ_INS_CH,
|
||||
SYSZ_INS_CHF,
|
||||
SYSZ_INS_CHHSI,
|
||||
SYSZ_INS_CHI,
|
||||
SYSZ_INS_CHRL,
|
||||
SYSZ_INS_CHSI,
|
||||
SYSZ_INS_CHY,
|
||||
SYSZ_INS_CIH,
|
||||
SYSZ_INS_CL,
|
||||
SYSZ_INS_CLC,
|
||||
SYSZ_INS_CLFDBR,
|
||||
SYSZ_INS_CLFEBR,
|
||||
SYSZ_INS_CLFHSI,
|
||||
SYSZ_INS_CLFI,
|
||||
SYSZ_INS_CLFXBR,
|
||||
SYSZ_INS_CLG,
|
||||
SYSZ_INS_CLGDBR,
|
||||
SYSZ_INS_CLGEBR,
|
||||
SYSZ_INS_CLGF,
|
||||
SYSZ_INS_CLGFI,
|
||||
SYSZ_INS_CLGFR,
|
||||
SYSZ_INS_CLGFRL,
|
||||
SYSZ_INS_CLGHRL,
|
||||
SYSZ_INS_CLGHSI,
|
||||
SYSZ_INS_CLGR,
|
||||
SYSZ_INS_CLGRL,
|
||||
SYSZ_INS_CLGXBR,
|
||||
SYSZ_INS_CLHF,
|
||||
SYSZ_INS_CLHHSI,
|
||||
SYSZ_INS_CLHRL,
|
||||
SYSZ_INS_CLI,
|
||||
SYSZ_INS_CLIH,
|
||||
SYSZ_INS_CLIY,
|
||||
SYSZ_INS_CLR,
|
||||
SYSZ_INS_CLRL,
|
||||
SYSZ_INS_CLST,
|
||||
SYSZ_INS_CLY,
|
||||
SYSZ_INS_CPSDR,
|
||||
SYSZ_INS_CR,
|
||||
SYSZ_INS_CRL,
|
||||
SYSZ_INS_CS,
|
||||
SYSZ_INS_CSG,
|
||||
SYSZ_INS_CSY,
|
||||
SYSZ_INS_CXBR,
|
||||
SYSZ_INS_CXFBR,
|
||||
SYSZ_INS_CXGBR,
|
||||
SYSZ_INS_CXLFBR,
|
||||
SYSZ_INS_CXLGBR,
|
||||
SYSZ_INS_CY,
|
||||
SYSZ_INS_DDB,
|
||||
SYSZ_INS_DDBR,
|
||||
SYSZ_INS_DEB,
|
||||
SYSZ_INS_DEBR,
|
||||
SYSZ_INS_DL,
|
||||
SYSZ_INS_DLG,
|
||||
SYSZ_INS_DLGR,
|
||||
SYSZ_INS_DLR,
|
||||
SYSZ_INS_DSG,
|
||||
SYSZ_INS_DSGF,
|
||||
SYSZ_INS_DSGFR,
|
||||
SYSZ_INS_DSGR,
|
||||
SYSZ_INS_DXBR,
|
||||
SYSZ_INS_EAR,
|
||||
SYSZ_INS_FIDBR,
|
||||
SYSZ_INS_FIDBRA,
|
||||
SYSZ_INS_FIEBR,
|
||||
SYSZ_INS_FIEBRA,
|
||||
SYSZ_INS_FIXBR,
|
||||
SYSZ_INS_FIXBRA,
|
||||
SYSZ_INS_FLOGR,
|
||||
SYSZ_INS_IC,
|
||||
SYSZ_INS_ICY,
|
||||
SYSZ_INS_IIHF,
|
||||
SYSZ_INS_IIHH,
|
||||
SYSZ_INS_IIHL,
|
||||
SYSZ_INS_IILF,
|
||||
SYSZ_INS_IILH,
|
||||
SYSZ_INS_IILL,
|
||||
SYSZ_INS_IPM,
|
||||
SYSZ_INS_L,
|
||||
SYSZ_INS_LA,
|
||||
SYSZ_INS_LAA,
|
||||
SYSZ_INS_LAAG,
|
||||
SYSZ_INS_LAAL,
|
||||
SYSZ_INS_LAALG,
|
||||
SYSZ_INS_LAN,
|
||||
SYSZ_INS_LANG,
|
||||
SYSZ_INS_LAO,
|
||||
SYSZ_INS_LAOG,
|
||||
SYSZ_INS_LARL,
|
||||
SYSZ_INS_LAX,
|
||||
SYSZ_INS_LAXG,
|
||||
SYSZ_INS_LAY,
|
||||
SYSZ_INS_LB,
|
||||
SYSZ_INS_LBH,
|
||||
SYSZ_INS_LBR,
|
||||
SYSZ_INS_LCDBR,
|
||||
SYSZ_INS_LCEBR,
|
||||
SYSZ_INS_LCGFR,
|
||||
SYSZ_INS_LCGR,
|
||||
SYSZ_INS_LCR,
|
||||
SYSZ_INS_LCXBR,
|
||||
SYSZ_INS_LD,
|
||||
SYSZ_INS_LDEB,
|
||||
SYSZ_INS_LDEBR,
|
||||
SYSZ_INS_LDGR,
|
||||
SYSZ_INS_LDR,
|
||||
SYSZ_INS_LDXBR,
|
||||
SYSZ_INS_LDXBRA,
|
||||
SYSZ_INS_LDY,
|
||||
SYSZ_INS_LE,
|
||||
SYSZ_INS_LEDBR,
|
||||
SYSZ_INS_LEDBRA,
|
||||
SYSZ_INS_LER,
|
||||
SYSZ_INS_LEXBR,
|
||||
SYSZ_INS_LEXBRA,
|
||||
SYSZ_INS_LEY,
|
||||
SYSZ_INS_LFH,
|
||||
SYSZ_INS_LG,
|
||||
SYSZ_INS_LGB,
|
||||
SYSZ_INS_LGBR,
|
||||
SYSZ_INS_LGDR,
|
||||
SYSZ_INS_LGF,
|
||||
SYSZ_INS_LGFI,
|
||||
SYSZ_INS_LGFR,
|
||||
SYSZ_INS_LGFRL,
|
||||
SYSZ_INS_LGH,
|
||||
SYSZ_INS_LGHI,
|
||||
SYSZ_INS_LGHR,
|
||||
SYSZ_INS_LGHRL,
|
||||
SYSZ_INS_LGR,
|
||||
SYSZ_INS_LGRL,
|
||||
SYSZ_INS_LH,
|
||||
SYSZ_INS_LHH,
|
||||
SYSZ_INS_LHI,
|
||||
SYSZ_INS_LHR,
|
||||
SYSZ_INS_LHRL,
|
||||
SYSZ_INS_LHY,
|
||||
SYSZ_INS_LLC,
|
||||
SYSZ_INS_LLCH,
|
||||
SYSZ_INS_LLCR,
|
||||
SYSZ_INS_LLGC,
|
||||
SYSZ_INS_LLGCR,
|
||||
SYSZ_INS_LLGF,
|
||||
SYSZ_INS_LLGFR,
|
||||
SYSZ_INS_LLGFRL,
|
||||
SYSZ_INS_LLGH,
|
||||
SYSZ_INS_LLGHR,
|
||||
SYSZ_INS_LLGHRL,
|
||||
SYSZ_INS_LLH,
|
||||
SYSZ_INS_LLHH,
|
||||
SYSZ_INS_LLHR,
|
||||
SYSZ_INS_LLHRL,
|
||||
SYSZ_INS_LLIHF,
|
||||
SYSZ_INS_LLIHH,
|
||||
SYSZ_INS_LLIHL,
|
||||
SYSZ_INS_LLILF,
|
||||
SYSZ_INS_LLILH,
|
||||
SYSZ_INS_LLILL,
|
||||
SYSZ_INS_LMG,
|
||||
SYSZ_INS_LNDBR,
|
||||
SYSZ_INS_LNEBR,
|
||||
SYSZ_INS_LNGFR,
|
||||
SYSZ_INS_LNGR,
|
||||
SYSZ_INS_LNR,
|
||||
SYSZ_INS_LNXBR,
|
||||
SYSZ_INS_LPDBR,
|
||||
SYSZ_INS_LPEBR,
|
||||
SYSZ_INS_LPGFR,
|
||||
SYSZ_INS_LPGR,
|
||||
SYSZ_INS_LPR,
|
||||
SYSZ_INS_LPXBR,
|
||||
SYSZ_INS_LR,
|
||||
SYSZ_INS_LRL,
|
||||
SYSZ_INS_LRV,
|
||||
SYSZ_INS_LRVG,
|
||||
SYSZ_INS_LRVGR,
|
||||
SYSZ_INS_LRVR,
|
||||
SYSZ_INS_LT,
|
||||
SYSZ_INS_LTDBR,
|
||||
SYSZ_INS_LTEBR,
|
||||
SYSZ_INS_LTG,
|
||||
SYSZ_INS_LTGF,
|
||||
SYSZ_INS_LTGFR,
|
||||
SYSZ_INS_LTGR,
|
||||
SYSZ_INS_LTR,
|
||||
SYSZ_INS_LTXBR,
|
||||
SYSZ_INS_LXDB,
|
||||
SYSZ_INS_LXDBR,
|
||||
SYSZ_INS_LXEB,
|
||||
SYSZ_INS_LXEBR,
|
||||
SYSZ_INS_LXR,
|
||||
SYSZ_INS_LY,
|
||||
SYSZ_INS_LZDR,
|
||||
SYSZ_INS_LZER,
|
||||
SYSZ_INS_LZXR,
|
||||
SYSZ_INS_MADB,
|
||||
SYSZ_INS_MADBR,
|
||||
SYSZ_INS_MAEB,
|
||||
SYSZ_INS_MAEBR,
|
||||
SYSZ_INS_MDB,
|
||||
SYSZ_INS_MDBR,
|
||||
SYSZ_INS_MDEB,
|
||||
SYSZ_INS_MDEBR,
|
||||
SYSZ_INS_MEEB,
|
||||
SYSZ_INS_MEEBR,
|
||||
SYSZ_INS_MGHI,
|
||||
SYSZ_INS_MH,
|
||||
SYSZ_INS_MHI,
|
||||
SYSZ_INS_MHY,
|
||||
SYSZ_INS_MLG,
|
||||
SYSZ_INS_MLGR,
|
||||
SYSZ_INS_MS,
|
||||
SYSZ_INS_MSDB,
|
||||
SYSZ_INS_MSDBR,
|
||||
SYSZ_INS_MSEB,
|
||||
SYSZ_INS_MSEBR,
|
||||
SYSZ_INS_MSFI,
|
||||
SYSZ_INS_MSG,
|
||||
SYSZ_INS_MSGF,
|
||||
SYSZ_INS_MSGFI,
|
||||
SYSZ_INS_MSGFR,
|
||||
SYSZ_INS_MSGR,
|
||||
SYSZ_INS_MSR,
|
||||
SYSZ_INS_MSY,
|
||||
SYSZ_INS_MVC,
|
||||
SYSZ_INS_MVGHI,
|
||||
SYSZ_INS_MVHHI,
|
||||
SYSZ_INS_MVHI,
|
||||
SYSZ_INS_MVI,
|
||||
SYSZ_INS_MVIY,
|
||||
SYSZ_INS_MVST,
|
||||
SYSZ_INS_MXBR,
|
||||
SYSZ_INS_MXDB,
|
||||
SYSZ_INS_MXDBR,
|
||||
SYSZ_INS_N,
|
||||
SYSZ_INS_NC,
|
||||
SYSZ_INS_NG,
|
||||
SYSZ_INS_NGR,
|
||||
SYSZ_INS_NGRK,
|
||||
SYSZ_INS_NI,
|
||||
SYSZ_INS_NIHF,
|
||||
SYSZ_INS_NIHH,
|
||||
SYSZ_INS_NIHL,
|
||||
SYSZ_INS_NILF,
|
||||
SYSZ_INS_NILH,
|
||||
SYSZ_INS_NILL,
|
||||
SYSZ_INS_NIY,
|
||||
SYSZ_INS_NR,
|
||||
SYSZ_INS_NRK,
|
||||
SYSZ_INS_NY,
|
||||
SYSZ_INS_O,
|
||||
SYSZ_INS_OC,
|
||||
SYSZ_INS_OG,
|
||||
SYSZ_INS_OGR,
|
||||
SYSZ_INS_OGRK,
|
||||
SYSZ_INS_OI,
|
||||
SYSZ_INS_OIHF,
|
||||
SYSZ_INS_OIHH,
|
||||
SYSZ_INS_OIHL,
|
||||
SYSZ_INS_OILF,
|
||||
SYSZ_INS_OILH,
|
||||
SYSZ_INS_OILL,
|
||||
SYSZ_INS_OIY,
|
||||
SYSZ_INS_OR,
|
||||
SYSZ_INS_ORK,
|
||||
SYSZ_INS_OY,
|
||||
SYSZ_INS_PFD,
|
||||
SYSZ_INS_PFDRL,
|
||||
SYSZ_INS_RISBG,
|
||||
SYSZ_INS_RISBHG,
|
||||
SYSZ_INS_RISBLG,
|
||||
SYSZ_INS_RLL,
|
||||
SYSZ_INS_RLLG,
|
||||
SYSZ_INS_RNSBG,
|
||||
SYSZ_INS_ROSBG,
|
||||
SYSZ_INS_RXSBG,
|
||||
SYSZ_INS_S,
|
||||
SYSZ_INS_SDB,
|
||||
SYSZ_INS_SDBR,
|
||||
SYSZ_INS_SEB,
|
||||
SYSZ_INS_SEBR,
|
||||
SYSZ_INS_SG,
|
||||
SYSZ_INS_SGF,
|
||||
SYSZ_INS_SGFR,
|
||||
SYSZ_INS_SGR,
|
||||
SYSZ_INS_SGRK,
|
||||
SYSZ_INS_SH,
|
||||
SYSZ_INS_SHY,
|
||||
SYSZ_INS_SL,
|
||||
SYSZ_INS_SLB,
|
||||
SYSZ_INS_SLBG,
|
||||
SYSZ_INS_SLBR,
|
||||
SYSZ_INS_SLFI,
|
||||
SYSZ_INS_SLG,
|
||||
SYSZ_INS_SLBGR,
|
||||
SYSZ_INS_SLGF,
|
||||
SYSZ_INS_SLGFI,
|
||||
SYSZ_INS_SLGFR,
|
||||
SYSZ_INS_SLGR,
|
||||
SYSZ_INS_SLGRK,
|
||||
SYSZ_INS_SLL,
|
||||
SYSZ_INS_SLLG,
|
||||
SYSZ_INS_SLLK,
|
||||
SYSZ_INS_SLR,
|
||||
SYSZ_INS_SLRK,
|
||||
SYSZ_INS_SLY,
|
||||
SYSZ_INS_SQDB,
|
||||
SYSZ_INS_SQDBR,
|
||||
SYSZ_INS_SQEB,
|
||||
SYSZ_INS_SQEBR,
|
||||
SYSZ_INS_SQXBR,
|
||||
SYSZ_INS_SR,
|
||||
SYSZ_INS_SRA,
|
||||
SYSZ_INS_SRAG,
|
||||
SYSZ_INS_SRAK,
|
||||
SYSZ_INS_SRK,
|
||||
SYSZ_INS_SRL,
|
||||
SYSZ_INS_SRLG,
|
||||
SYSZ_INS_SRLK,
|
||||
SYSZ_INS_SRST,
|
||||
SYSZ_INS_ST,
|
||||
SYSZ_INS_STC,
|
||||
SYSZ_INS_STCH,
|
||||
SYSZ_INS_STCY,
|
||||
SYSZ_INS_STD,
|
||||
SYSZ_INS_STDY,
|
||||
SYSZ_INS_STE,
|
||||
SYSZ_INS_STEY,
|
||||
SYSZ_INS_STFH,
|
||||
SYSZ_INS_STG,
|
||||
SYSZ_INS_STGRL,
|
||||
SYSZ_INS_STH,
|
||||
SYSZ_INS_STHH,
|
||||
SYSZ_INS_STHRL,
|
||||
SYSZ_INS_STHY,
|
||||
SYSZ_INS_STMG,
|
||||
SYSZ_INS_STRL,
|
||||
SYSZ_INS_STRV,
|
||||
SYSZ_INS_STRVG,
|
||||
SYSZ_INS_STY,
|
||||
SYSZ_INS_SXBR,
|
||||
SYSZ_INS_SY,
|
||||
SYSZ_INS_TM,
|
||||
SYSZ_INS_TMHH,
|
||||
SYSZ_INS_TMHL,
|
||||
SYSZ_INS_TMLH,
|
||||
SYSZ_INS_TMLL,
|
||||
SYSZ_INS_TMY,
|
||||
SYSZ_INS_X,
|
||||
SYSZ_INS_XC,
|
||||
SYSZ_INS_XG,
|
||||
SYSZ_INS_XGR,
|
||||
SYSZ_INS_XGRK,
|
||||
SYSZ_INS_XI,
|
||||
SYSZ_INS_XIHF,
|
||||
SYSZ_INS_XILF,
|
||||
SYSZ_INS_XIY,
|
||||
SYSZ_INS_XR,
|
||||
SYSZ_INS_XRK,
|
||||
SYSZ_INS_XY,
|
||||
|
||||
SYSZ_INS_ENDING, // <-- mark the end of the list of instructions
|
||||
} sysz_insn;
|
||||
|
||||
/// Group of SystemZ instructions
|
||||
typedef enum sysz_insn_group {
|
||||
SYSZ_GRP_INVALID = 0, ///< = CS_GRP_INVALID
|
||||
|
||||
// Generic groups
|
||||
// all jump instructions (conditional+direct+indirect jumps)
|
||||
SYSZ_GRP_JUMP, ///< = CS_GRP_JUMP
|
||||
|
||||
// Architecture-specific groups
|
||||
SYSZ_GRP_DISTINCTOPS = 128,
|
||||
SYSZ_GRP_FPEXTENSION,
|
||||
SYSZ_GRP_HIGHWORD,
|
||||
SYSZ_GRP_INTERLOCKEDACCESS1,
|
||||
SYSZ_GRP_LOADSTOREONCOND,
|
||||
|
||||
SYSZ_GRP_ENDING, // <-- mark the end of the list of groups
|
||||
} sysz_insn_group;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,359 @@
|
||||
/* Capstone Disassembly Engine */
|
||||
/* TMS320C64x Backend by Fotis Loukos <me@fotisl.com> 2016 */
|
||||
|
||||
#ifndef CAPSTONE_TMS320C64X_H
|
||||
#define CAPSTONE_TMS320C64X_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
typedef enum tms320c64x_op_type {
|
||||
TMS320C64X_OP_INVALID = 0, ///< = CS_OP_INVALID (Uninitialized).
|
||||
TMS320C64X_OP_REG, ///< = CS_OP_REG (Register operand).
|
||||
TMS320C64X_OP_IMM, ///< = CS_OP_IMM (Immediate operand).
|
||||
TMS320C64X_OP_MEM, ///< = CS_OP_MEM (Memory operand).
|
||||
TMS320C64X_OP_REGPAIR = 64, ///< Register pair for double word ops
|
||||
} tms320c64x_op_type;
|
||||
|
||||
typedef enum tms320c64x_mem_disp {
|
||||
TMS320C64X_MEM_DISP_INVALID = 0,
|
||||
TMS320C64X_MEM_DISP_CONSTANT,
|
||||
TMS320C64X_MEM_DISP_REGISTER,
|
||||
} tms320c64x_mem_disp;
|
||||
|
||||
typedef enum tms320c64x_mem_dir {
|
||||
TMS320C64X_MEM_DIR_INVALID = 0,
|
||||
TMS320C64X_MEM_DIR_FW,
|
||||
TMS320C64X_MEM_DIR_BW,
|
||||
} tms320c64x_mem_dir;
|
||||
|
||||
typedef enum tms320c64x_mem_mod {
|
||||
TMS320C64X_MEM_MOD_INVALID = 0,
|
||||
TMS320C64X_MEM_MOD_NO,
|
||||
TMS320C64X_MEM_MOD_PRE,
|
||||
TMS320C64X_MEM_MOD_POST,
|
||||
} tms320c64x_mem_mod;
|
||||
|
||||
typedef struct tms320c64x_op_mem {
|
||||
unsigned int base; ///< base register
|
||||
unsigned int disp; ///< displacement/offset value
|
||||
unsigned int unit; ///< unit of base and offset register
|
||||
unsigned int scaled; ///< offset scaled
|
||||
unsigned int disptype; ///< displacement type
|
||||
unsigned int direction; ///< direction
|
||||
unsigned int modify; ///< modification
|
||||
} tms320c64x_op_mem;
|
||||
|
||||
typedef struct cs_tms320c64x_op {
|
||||
tms320c64x_op_type type; ///< operand type
|
||||
union {
|
||||
unsigned int reg; ///< register value for REG operand or first register for REGPAIR operand
|
||||
int32_t imm; ///< immediate value for IMM operand
|
||||
tms320c64x_op_mem mem; ///< base/disp value for MEM operand
|
||||
};
|
||||
} cs_tms320c64x_op;
|
||||
|
||||
typedef struct cs_tms320c64x {
|
||||
uint8_t op_count;
|
||||
cs_tms320c64x_op operands[8]; ///< operands for this instruction.
|
||||
struct {
|
||||
unsigned int reg;
|
||||
unsigned int zero;
|
||||
} condition;
|
||||
struct {
|
||||
unsigned int unit;
|
||||
unsigned int side;
|
||||
unsigned int crosspath;
|
||||
} funit;
|
||||
unsigned int parallel;
|
||||
} cs_tms320c64x;
|
||||
|
||||
typedef enum tms320c64x_reg {
|
||||
TMS320C64X_REG_INVALID = 0,
|
||||
|
||||
TMS320C64X_REG_AMR,
|
||||
TMS320C64X_REG_CSR,
|
||||
TMS320C64X_REG_DIER,
|
||||
TMS320C64X_REG_DNUM,
|
||||
TMS320C64X_REG_ECR,
|
||||
TMS320C64X_REG_GFPGFR,
|
||||
TMS320C64X_REG_GPLYA,
|
||||
TMS320C64X_REG_GPLYB,
|
||||
TMS320C64X_REG_ICR,
|
||||
TMS320C64X_REG_IER,
|
||||
TMS320C64X_REG_IERR,
|
||||
TMS320C64X_REG_ILC,
|
||||
TMS320C64X_REG_IRP,
|
||||
TMS320C64X_REG_ISR,
|
||||
TMS320C64X_REG_ISTP,
|
||||
TMS320C64X_REG_ITSR,
|
||||
TMS320C64X_REG_NRP,
|
||||
TMS320C64X_REG_NTSR,
|
||||
TMS320C64X_REG_REP,
|
||||
TMS320C64X_REG_RILC,
|
||||
TMS320C64X_REG_SSR,
|
||||
TMS320C64X_REG_TSCH,
|
||||
TMS320C64X_REG_TSCL,
|
||||
TMS320C64X_REG_TSR,
|
||||
TMS320C64X_REG_A0,
|
||||
TMS320C64X_REG_A1,
|
||||
TMS320C64X_REG_A2,
|
||||
TMS320C64X_REG_A3,
|
||||
TMS320C64X_REG_A4,
|
||||
TMS320C64X_REG_A5,
|
||||
TMS320C64X_REG_A6,
|
||||
TMS320C64X_REG_A7,
|
||||
TMS320C64X_REG_A8,
|
||||
TMS320C64X_REG_A9,
|
||||
TMS320C64X_REG_A10,
|
||||
TMS320C64X_REG_A11,
|
||||
TMS320C64X_REG_A12,
|
||||
TMS320C64X_REG_A13,
|
||||
TMS320C64X_REG_A14,
|
||||
TMS320C64X_REG_A15,
|
||||
TMS320C64X_REG_A16,
|
||||
TMS320C64X_REG_A17,
|
||||
TMS320C64X_REG_A18,
|
||||
TMS320C64X_REG_A19,
|
||||
TMS320C64X_REG_A20,
|
||||
TMS320C64X_REG_A21,
|
||||
TMS320C64X_REG_A22,
|
||||
TMS320C64X_REG_A23,
|
||||
TMS320C64X_REG_A24,
|
||||
TMS320C64X_REG_A25,
|
||||
TMS320C64X_REG_A26,
|
||||
TMS320C64X_REG_A27,
|
||||
TMS320C64X_REG_A28,
|
||||
TMS320C64X_REG_A29,
|
||||
TMS320C64X_REG_A30,
|
||||
TMS320C64X_REG_A31,
|
||||
TMS320C64X_REG_B0,
|
||||
TMS320C64X_REG_B1,
|
||||
TMS320C64X_REG_B2,
|
||||
TMS320C64X_REG_B3,
|
||||
TMS320C64X_REG_B4,
|
||||
TMS320C64X_REG_B5,
|
||||
TMS320C64X_REG_B6,
|
||||
TMS320C64X_REG_B7,
|
||||
TMS320C64X_REG_B8,
|
||||
TMS320C64X_REG_B9,
|
||||
TMS320C64X_REG_B10,
|
||||
TMS320C64X_REG_B11,
|
||||
TMS320C64X_REG_B12,
|
||||
TMS320C64X_REG_B13,
|
||||
TMS320C64X_REG_B14,
|
||||
TMS320C64X_REG_B15,
|
||||
TMS320C64X_REG_B16,
|
||||
TMS320C64X_REG_B17,
|
||||
TMS320C64X_REG_B18,
|
||||
TMS320C64X_REG_B19,
|
||||
TMS320C64X_REG_B20,
|
||||
TMS320C64X_REG_B21,
|
||||
TMS320C64X_REG_B22,
|
||||
TMS320C64X_REG_B23,
|
||||
TMS320C64X_REG_B24,
|
||||
TMS320C64X_REG_B25,
|
||||
TMS320C64X_REG_B26,
|
||||
TMS320C64X_REG_B27,
|
||||
TMS320C64X_REG_B28,
|
||||
TMS320C64X_REG_B29,
|
||||
TMS320C64X_REG_B30,
|
||||
TMS320C64X_REG_B31,
|
||||
TMS320C64X_REG_PCE1,
|
||||
|
||||
TMS320C64X_REG_ENDING, // <-- mark the end of the list of registers
|
||||
|
||||
// Alias registers
|
||||
TMS320C64X_REG_EFR = TMS320C64X_REG_ECR,
|
||||
TMS320C64X_REG_IFR = TMS320C64X_REG_ISR,
|
||||
} tms320c64x_reg;
|
||||
|
||||
typedef enum tms320c64x_insn {
|
||||
TMS320C64X_INS_INVALID = 0,
|
||||
|
||||
TMS320C64X_INS_ABS,
|
||||
TMS320C64X_INS_ABS2,
|
||||
TMS320C64X_INS_ADD,
|
||||
TMS320C64X_INS_ADD2,
|
||||
TMS320C64X_INS_ADD4,
|
||||
TMS320C64X_INS_ADDAB,
|
||||
TMS320C64X_INS_ADDAD,
|
||||
TMS320C64X_INS_ADDAH,
|
||||
TMS320C64X_INS_ADDAW,
|
||||
TMS320C64X_INS_ADDK,
|
||||
TMS320C64X_INS_ADDKPC,
|
||||
TMS320C64X_INS_ADDU,
|
||||
TMS320C64X_INS_AND,
|
||||
TMS320C64X_INS_ANDN,
|
||||
TMS320C64X_INS_AVG2,
|
||||
TMS320C64X_INS_AVGU4,
|
||||
TMS320C64X_INS_B,
|
||||
TMS320C64X_INS_BDEC,
|
||||
TMS320C64X_INS_BITC4,
|
||||
TMS320C64X_INS_BNOP,
|
||||
TMS320C64X_INS_BPOS,
|
||||
TMS320C64X_INS_CLR,
|
||||
TMS320C64X_INS_CMPEQ,
|
||||
TMS320C64X_INS_CMPEQ2,
|
||||
TMS320C64X_INS_CMPEQ4,
|
||||
TMS320C64X_INS_CMPGT,
|
||||
TMS320C64X_INS_CMPGT2,
|
||||
TMS320C64X_INS_CMPGTU4,
|
||||
TMS320C64X_INS_CMPLT,
|
||||
TMS320C64X_INS_CMPLTU,
|
||||
TMS320C64X_INS_DEAL,
|
||||
TMS320C64X_INS_DOTP2,
|
||||
TMS320C64X_INS_DOTPN2,
|
||||
TMS320C64X_INS_DOTPNRSU2,
|
||||
TMS320C64X_INS_DOTPRSU2,
|
||||
TMS320C64X_INS_DOTPSU4,
|
||||
TMS320C64X_INS_DOTPU4,
|
||||
TMS320C64X_INS_EXT,
|
||||
TMS320C64X_INS_EXTU,
|
||||
TMS320C64X_INS_GMPGTU,
|
||||
TMS320C64X_INS_GMPY4,
|
||||
TMS320C64X_INS_LDB,
|
||||
TMS320C64X_INS_LDBU,
|
||||
TMS320C64X_INS_LDDW,
|
||||
TMS320C64X_INS_LDH,
|
||||
TMS320C64X_INS_LDHU,
|
||||
TMS320C64X_INS_LDNDW,
|
||||
TMS320C64X_INS_LDNW,
|
||||
TMS320C64X_INS_LDW,
|
||||
TMS320C64X_INS_LMBD,
|
||||
TMS320C64X_INS_MAX2,
|
||||
TMS320C64X_INS_MAXU4,
|
||||
TMS320C64X_INS_MIN2,
|
||||
TMS320C64X_INS_MINU4,
|
||||
TMS320C64X_INS_MPY,
|
||||
TMS320C64X_INS_MPY2,
|
||||
TMS320C64X_INS_MPYH,
|
||||
TMS320C64X_INS_MPYHI,
|
||||
TMS320C64X_INS_MPYHIR,
|
||||
TMS320C64X_INS_MPYHL,
|
||||
TMS320C64X_INS_MPYHLU,
|
||||
TMS320C64X_INS_MPYHSLU,
|
||||
TMS320C64X_INS_MPYHSU,
|
||||
TMS320C64X_INS_MPYHU,
|
||||
TMS320C64X_INS_MPYHULS,
|
||||
TMS320C64X_INS_MPYHUS,
|
||||
TMS320C64X_INS_MPYLH,
|
||||
TMS320C64X_INS_MPYLHU,
|
||||
TMS320C64X_INS_MPYLI,
|
||||
TMS320C64X_INS_MPYLIR,
|
||||
TMS320C64X_INS_MPYLSHU,
|
||||
TMS320C64X_INS_MPYLUHS,
|
||||
TMS320C64X_INS_MPYSU,
|
||||
TMS320C64X_INS_MPYSU4,
|
||||
TMS320C64X_INS_MPYU,
|
||||
TMS320C64X_INS_MPYU4,
|
||||
TMS320C64X_INS_MPYUS,
|
||||
TMS320C64X_INS_MVC,
|
||||
TMS320C64X_INS_MVD,
|
||||
TMS320C64X_INS_MVK,
|
||||
TMS320C64X_INS_MVKL,
|
||||
TMS320C64X_INS_MVKLH,
|
||||
TMS320C64X_INS_NOP,
|
||||
TMS320C64X_INS_NORM,
|
||||
TMS320C64X_INS_OR,
|
||||
TMS320C64X_INS_PACK2,
|
||||
TMS320C64X_INS_PACKH2,
|
||||
TMS320C64X_INS_PACKH4,
|
||||
TMS320C64X_INS_PACKHL2,
|
||||
TMS320C64X_INS_PACKL4,
|
||||
TMS320C64X_INS_PACKLH2,
|
||||
TMS320C64X_INS_ROTL,
|
||||
TMS320C64X_INS_SADD,
|
||||
TMS320C64X_INS_SADD2,
|
||||
TMS320C64X_INS_SADDU4,
|
||||
TMS320C64X_INS_SADDUS2,
|
||||
TMS320C64X_INS_SAT,
|
||||
TMS320C64X_INS_SET,
|
||||
TMS320C64X_INS_SHFL,
|
||||
TMS320C64X_INS_SHL,
|
||||
TMS320C64X_INS_SHLMB,
|
||||
TMS320C64X_INS_SHR,
|
||||
TMS320C64X_INS_SHR2,
|
||||
TMS320C64X_INS_SHRMB,
|
||||
TMS320C64X_INS_SHRU,
|
||||
TMS320C64X_INS_SHRU2,
|
||||
TMS320C64X_INS_SMPY,
|
||||
TMS320C64X_INS_SMPY2,
|
||||
TMS320C64X_INS_SMPYH,
|
||||
TMS320C64X_INS_SMPYHL,
|
||||
TMS320C64X_INS_SMPYLH,
|
||||
TMS320C64X_INS_SPACK2,
|
||||
TMS320C64X_INS_SPACKU4,
|
||||
TMS320C64X_INS_SSHL,
|
||||
TMS320C64X_INS_SSHVL,
|
||||
TMS320C64X_INS_SSHVR,
|
||||
TMS320C64X_INS_SSUB,
|
||||
TMS320C64X_INS_STB,
|
||||
TMS320C64X_INS_STDW,
|
||||
TMS320C64X_INS_STH,
|
||||
TMS320C64X_INS_STNDW,
|
||||
TMS320C64X_INS_STNW,
|
||||
TMS320C64X_INS_STW,
|
||||
TMS320C64X_INS_SUB,
|
||||
TMS320C64X_INS_SUB2,
|
||||
TMS320C64X_INS_SUB4,
|
||||
TMS320C64X_INS_SUBAB,
|
||||
TMS320C64X_INS_SUBABS4,
|
||||
TMS320C64X_INS_SUBAH,
|
||||
TMS320C64X_INS_SUBAW,
|
||||
TMS320C64X_INS_SUBC,
|
||||
TMS320C64X_INS_SUBU,
|
||||
TMS320C64X_INS_SWAP4,
|
||||
TMS320C64X_INS_UNPKHU4,
|
||||
TMS320C64X_INS_UNPKLU4,
|
||||
TMS320C64X_INS_XOR,
|
||||
TMS320C64X_INS_XPND2,
|
||||
TMS320C64X_INS_XPND4,
|
||||
// Aliases
|
||||
TMS320C64X_INS_IDLE,
|
||||
TMS320C64X_INS_MV,
|
||||
TMS320C64X_INS_NEG,
|
||||
TMS320C64X_INS_NOT,
|
||||
TMS320C64X_INS_SWAP2,
|
||||
TMS320C64X_INS_ZERO,
|
||||
|
||||
TMS320C64X_INS_ENDING, // <-- mark the end of the list of instructions
|
||||
} tms320c64x_insn;
|
||||
|
||||
typedef enum tms320c64x_insn_group {
|
||||
TMS320C64X_GRP_INVALID = 0, ///< = CS_GRP_INVALID
|
||||
|
||||
TMS320C64X_GRP_JUMP, ///< = CS_GRP_JUMP
|
||||
|
||||
TMS320C64X_GRP_FUNIT_D = 128,
|
||||
TMS320C64X_GRP_FUNIT_L,
|
||||
TMS320C64X_GRP_FUNIT_M,
|
||||
TMS320C64X_GRP_FUNIT_S,
|
||||
TMS320C64X_GRP_FUNIT_NO,
|
||||
|
||||
TMS320C64X_GRP_ENDING, // <-- mark the end of the list of groups
|
||||
} tms320c64x_insn_group;
|
||||
|
||||
typedef enum tms320c64x_funit {
|
||||
TMS320C64X_FUNIT_INVALID = 0,
|
||||
TMS320C64X_FUNIT_D,
|
||||
TMS320C64X_FUNIT_L,
|
||||
TMS320C64X_FUNIT_M,
|
||||
TMS320C64X_FUNIT_S,
|
||||
TMS320C64X_FUNIT_NO
|
||||
} tms320c64x_funit;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,235 @@
|
||||
#ifndef CAPSTONE_XCORE_H
|
||||
#define CAPSTONE_XCORE_H
|
||||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2014-2015 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
/// Operand type for instruction's operands
|
||||
typedef enum xcore_op_type {
|
||||
XCORE_OP_INVALID = 0, ///< = CS_OP_INVALID (Uninitialized).
|
||||
XCORE_OP_REG, ///< = CS_OP_REG (Register operand).
|
||||
XCORE_OP_IMM, ///< = CS_OP_IMM (Immediate operand).
|
||||
XCORE_OP_MEM, ///< = CS_OP_MEM (Memory operand).
|
||||
} xcore_op_type;
|
||||
|
||||
/// XCore registers
|
||||
typedef enum xcore_reg {
|
||||
XCORE_REG_INVALID = 0,
|
||||
|
||||
XCORE_REG_CP,
|
||||
XCORE_REG_DP,
|
||||
XCORE_REG_LR,
|
||||
XCORE_REG_SP,
|
||||
XCORE_REG_R0,
|
||||
XCORE_REG_R1,
|
||||
XCORE_REG_R2,
|
||||
XCORE_REG_R3,
|
||||
XCORE_REG_R4,
|
||||
XCORE_REG_R5,
|
||||
XCORE_REG_R6,
|
||||
XCORE_REG_R7,
|
||||
XCORE_REG_R8,
|
||||
XCORE_REG_R9,
|
||||
XCORE_REG_R10,
|
||||
XCORE_REG_R11,
|
||||
|
||||
// pseudo registers
|
||||
XCORE_REG_PC, ///< pc
|
||||
|
||||
// internal thread registers
|
||||
// see The-XMOS-XS1-Architecture(X7879A).pdf
|
||||
XCORE_REG_SCP, ///< save pc
|
||||
XCORE_REG_SSR, //< save status
|
||||
XCORE_REG_ET, //< exception type
|
||||
XCORE_REG_ED, //< exception data
|
||||
XCORE_REG_SED, //< save exception data
|
||||
XCORE_REG_KEP, //< kernel entry pointer
|
||||
XCORE_REG_KSP, //< kernel stack pointer
|
||||
XCORE_REG_ID, //< thread ID
|
||||
|
||||
XCORE_REG_ENDING, // <-- mark the end of the list of registers
|
||||
} xcore_reg;
|
||||
|
||||
/// Instruction's operand referring to memory
|
||||
/// This is associated with XCORE_OP_MEM operand type above
|
||||
typedef struct xcore_op_mem {
|
||||
uint8_t base; ///< base register, can be safely interpreted as
|
||||
///< a value of type `xcore_reg`, but it is only
|
||||
///< one byte wide
|
||||
uint8_t index; ///< index register, same conditions apply here
|
||||
int32_t disp; ///< displacement/offset value
|
||||
int direct; ///< +1: forward, -1: backward
|
||||
} xcore_op_mem;
|
||||
|
||||
/// Instruction operand
|
||||
typedef struct cs_xcore_op {
|
||||
xcore_op_type type; ///< operand type
|
||||
union {
|
||||
xcore_reg reg; ///< register value for REG operand
|
||||
int32_t imm; ///< immediate value for IMM operand
|
||||
xcore_op_mem mem; ///< base/disp value for MEM operand
|
||||
};
|
||||
} cs_xcore_op;
|
||||
|
||||
/// Instruction structure
|
||||
typedef struct cs_xcore {
|
||||
/// Number of operands of this instruction,
|
||||
/// or 0 when instruction has no operand.
|
||||
uint8_t op_count;
|
||||
cs_xcore_op operands[8]; ///< operands for this instruction.
|
||||
} cs_xcore;
|
||||
|
||||
/// XCore instruction
|
||||
typedef enum xcore_insn {
|
||||
XCORE_INS_INVALID = 0,
|
||||
|
||||
XCORE_INS_ADD,
|
||||
XCORE_INS_ANDNOT,
|
||||
XCORE_INS_AND,
|
||||
XCORE_INS_ASHR,
|
||||
XCORE_INS_BAU,
|
||||
XCORE_INS_BITREV,
|
||||
XCORE_INS_BLA,
|
||||
XCORE_INS_BLAT,
|
||||
XCORE_INS_BL,
|
||||
XCORE_INS_BF,
|
||||
XCORE_INS_BT,
|
||||
XCORE_INS_BU,
|
||||
XCORE_INS_BRU,
|
||||
XCORE_INS_BYTEREV,
|
||||
XCORE_INS_CHKCT,
|
||||
XCORE_INS_CLRE,
|
||||
XCORE_INS_CLRPT,
|
||||
XCORE_INS_CLRSR,
|
||||
XCORE_INS_CLZ,
|
||||
XCORE_INS_CRC8,
|
||||
XCORE_INS_CRC32,
|
||||
XCORE_INS_DCALL,
|
||||
XCORE_INS_DENTSP,
|
||||
XCORE_INS_DGETREG,
|
||||
XCORE_INS_DIVS,
|
||||
XCORE_INS_DIVU,
|
||||
XCORE_INS_DRESTSP,
|
||||
XCORE_INS_DRET,
|
||||
XCORE_INS_ECALLF,
|
||||
XCORE_INS_ECALLT,
|
||||
XCORE_INS_EDU,
|
||||
XCORE_INS_EEF,
|
||||
XCORE_INS_EET,
|
||||
XCORE_INS_EEU,
|
||||
XCORE_INS_ENDIN,
|
||||
XCORE_INS_ENTSP,
|
||||
XCORE_INS_EQ,
|
||||
XCORE_INS_EXTDP,
|
||||
XCORE_INS_EXTSP,
|
||||
XCORE_INS_FREER,
|
||||
XCORE_INS_FREET,
|
||||
XCORE_INS_GETD,
|
||||
XCORE_INS_GET,
|
||||
XCORE_INS_GETN,
|
||||
XCORE_INS_GETR,
|
||||
XCORE_INS_GETSR,
|
||||
XCORE_INS_GETST,
|
||||
XCORE_INS_GETTS,
|
||||
XCORE_INS_INCT,
|
||||
XCORE_INS_INIT,
|
||||
XCORE_INS_INPW,
|
||||
XCORE_INS_INSHR,
|
||||
XCORE_INS_INT,
|
||||
XCORE_INS_IN,
|
||||
XCORE_INS_KCALL,
|
||||
XCORE_INS_KENTSP,
|
||||
XCORE_INS_KRESTSP,
|
||||
XCORE_INS_KRET,
|
||||
XCORE_INS_LADD,
|
||||
XCORE_INS_LD16S,
|
||||
XCORE_INS_LD8U,
|
||||
XCORE_INS_LDA16,
|
||||
XCORE_INS_LDAP,
|
||||
XCORE_INS_LDAW,
|
||||
XCORE_INS_LDC,
|
||||
XCORE_INS_LDW,
|
||||
XCORE_INS_LDIVU,
|
||||
XCORE_INS_LMUL,
|
||||
XCORE_INS_LSS,
|
||||
XCORE_INS_LSUB,
|
||||
XCORE_INS_LSU,
|
||||
XCORE_INS_MACCS,
|
||||
XCORE_INS_MACCU,
|
||||
XCORE_INS_MJOIN,
|
||||
XCORE_INS_MKMSK,
|
||||
XCORE_INS_MSYNC,
|
||||
XCORE_INS_MUL,
|
||||
XCORE_INS_NEG,
|
||||
XCORE_INS_NOT,
|
||||
XCORE_INS_OR,
|
||||
XCORE_INS_OUTCT,
|
||||
XCORE_INS_OUTPW,
|
||||
XCORE_INS_OUTSHR,
|
||||
XCORE_INS_OUTT,
|
||||
XCORE_INS_OUT,
|
||||
XCORE_INS_PEEK,
|
||||
XCORE_INS_REMS,
|
||||
XCORE_INS_REMU,
|
||||
XCORE_INS_RETSP,
|
||||
XCORE_INS_SETCLK,
|
||||
XCORE_INS_SET,
|
||||
XCORE_INS_SETC,
|
||||
XCORE_INS_SETD,
|
||||
XCORE_INS_SETEV,
|
||||
XCORE_INS_SETN,
|
||||
XCORE_INS_SETPSC,
|
||||
XCORE_INS_SETPT,
|
||||
XCORE_INS_SETRDY,
|
||||
XCORE_INS_SETSR,
|
||||
XCORE_INS_SETTW,
|
||||
XCORE_INS_SETV,
|
||||
XCORE_INS_SEXT,
|
||||
XCORE_INS_SHL,
|
||||
XCORE_INS_SHR,
|
||||
XCORE_INS_SSYNC,
|
||||
XCORE_INS_ST16,
|
||||
XCORE_INS_ST8,
|
||||
XCORE_INS_STW,
|
||||
XCORE_INS_SUB,
|
||||
XCORE_INS_SYNCR,
|
||||
XCORE_INS_TESTCT,
|
||||
XCORE_INS_TESTLCL,
|
||||
XCORE_INS_TESTWCT,
|
||||
XCORE_INS_TSETMR,
|
||||
XCORE_INS_START,
|
||||
XCORE_INS_WAITEF,
|
||||
XCORE_INS_WAITET,
|
||||
XCORE_INS_WAITEU,
|
||||
XCORE_INS_XOR,
|
||||
XCORE_INS_ZEXT,
|
||||
|
||||
XCORE_INS_ENDING, // <-- mark the end of the list of instructions
|
||||
} xcore_insn;
|
||||
|
||||
/// Group of XCore instructions
|
||||
typedef enum xcore_insn_group {
|
||||
XCORE_GRP_INVALID = 0, ///< = CS_GRP_INVALID
|
||||
|
||||
// Generic groups
|
||||
// all jump instructions (conditional+direct+indirect jumps)
|
||||
XCORE_GRP_JUMP, ///< = CS_GRP_JUMP
|
||||
|
||||
XCORE_GRP_ENDING, // <-- mark the end of the list of groups
|
||||
} xcore_insn_group;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,110 @@
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Axel Souchet & Nguyen Anh Quynh, 2014 */
|
||||
|
||||
#ifndef CAPSTONE_PLATFORM_H
|
||||
#define CAPSTONE_PLATFORM_H
|
||||
|
||||
// handle C99 issue (for pre-2013 VisualStudio)
|
||||
#if !defined(__CYGWIN__) && !defined(__MINGW32__) && !defined(__MINGW64__) && (defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64))
|
||||
// MSVC
|
||||
|
||||
// stdbool.h
|
||||
#if (_MSC_VER < 1800) || defined(_KERNEL_MODE)
|
||||
// this system does not have stdbool.h
|
||||
#ifndef __cplusplus
|
||||
typedef unsigned char bool;
|
||||
#define false 0
|
||||
#define true 1
|
||||
#endif
|
||||
|
||||
#else
|
||||
// VisualStudio 2013+ -> C99 is supported
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#else
|
||||
// not MSVC -> C99 is supported
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
|
||||
// handle C99 issue (for pre-2013 VisualStudio)
|
||||
#if defined(CAPSTONE_HAS_OSXKERNEL) || (defined(_MSC_VER) && (_MSC_VER <= 1700 || defined(_KERNEL_MODE)))
|
||||
// this system does not have inttypes.h
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1600 || defined(_KERNEL_MODE))
|
||||
// this system does not have stdint.h
|
||||
typedef signed char int8_t;
|
||||
typedef signed short int16_t;
|
||||
typedef signed int int32_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef signed long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
|
||||
#define INT8_MIN (-127i8 - 1)
|
||||
#define INT16_MIN (-32767i16 - 1)
|
||||
#define INT32_MIN (-2147483647i32 - 1)
|
||||
#define INT64_MIN (-9223372036854775807i64 - 1)
|
||||
#define INT8_MAX 127i8
|
||||
#define INT16_MAX 32767i16
|
||||
#define INT32_MAX 2147483647i32
|
||||
#define INT64_MAX 9223372036854775807i64
|
||||
#define UINT8_MAX 0xffui8
|
||||
#define UINT16_MAX 0xffffui16
|
||||
#define UINT32_MAX 0xffffffffui32
|
||||
#define UINT64_MAX 0xffffffffffffffffui64
|
||||
#endif
|
||||
|
||||
#define __PRI_8_LENGTH_MODIFIER__ "hh"
|
||||
#define __PRI_64_LENGTH_MODIFIER__ "ll"
|
||||
|
||||
#define PRId8 __PRI_8_LENGTH_MODIFIER__ "d"
|
||||
#define PRIi8 __PRI_8_LENGTH_MODIFIER__ "i"
|
||||
#define PRIo8 __PRI_8_LENGTH_MODIFIER__ "o"
|
||||
#define PRIu8 __PRI_8_LENGTH_MODIFIER__ "u"
|
||||
#define PRIx8 __PRI_8_LENGTH_MODIFIER__ "x"
|
||||
#define PRIX8 __PRI_8_LENGTH_MODIFIER__ "X"
|
||||
|
||||
#define PRId16 "hd"
|
||||
#define PRIi16 "hi"
|
||||
#define PRIo16 "ho"
|
||||
#define PRIu16 "hu"
|
||||
#define PRIx16 "hx"
|
||||
#define PRIX16 "hX"
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1700
|
||||
#define PRId32 "ld"
|
||||
#define PRIi32 "li"
|
||||
#define PRIo32 "lo"
|
||||
#define PRIu32 "lu"
|
||||
#define PRIx32 "lx"
|
||||
#define PRIX32 "lX"
|
||||
#else // OSX
|
||||
#define PRId32 "d"
|
||||
#define PRIi32 "i"
|
||||
#define PRIo32 "o"
|
||||
#define PRIu32 "u"
|
||||
#define PRIx32 "x"
|
||||
#define PRIX32 "X"
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1700
|
||||
// redefine functions from inttypes.h used in cstool
|
||||
#define strtoull _strtoui64
|
||||
#endif
|
||||
|
||||
#define PRId64 __PRI_64_LENGTH_MODIFIER__ "d"
|
||||
#define PRIi64 __PRI_64_LENGTH_MODIFIER__ "i"
|
||||
#define PRIo64 __PRI_64_LENGTH_MODIFIER__ "o"
|
||||
#define PRIu64 __PRI_64_LENGTH_MODIFIER__ "u"
|
||||
#define PRIx64 __PRI_64_LENGTH_MODIFIER__ "x"
|
||||
#define PRIX64 __PRI_64_LENGTH_MODIFIER__ "X"
|
||||
|
||||
#else
|
||||
// this system has inttypes.h by default
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
#if defined(_MSC_VER) && defined(_WIN32_WCE) && (_WIN32_WCE < 0x800) && !defined(__INTRIN_H_) && !defined(_INTRIN)
|
||||
#define _STDINT
|
||||
|
||||
#ifdef _M_ARM
|
||||
#include <armintr.h>
|
||||
#if (_WIN32_WCE >= 0x700) && defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__)
|
||||
#include <arm_neon.h>
|
||||
#endif
|
||||
#endif // _M_ARM
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,133 @@
|
||||
|
||||
#if defined(_MSC_VER) && defined(_WIN32_WCE) && (_WIN32_WCE < 0x800) && !defined(_STDINT_H_) && !defined(_STDINT)
|
||||
#define _STDINT
|
||||
|
||||
typedef __int8
|
||||
int8_t,
|
||||
int_least8_t;
|
||||
|
||||
typedef __int16
|
||||
int16_t,
|
||||
int_least16_t;
|
||||
|
||||
typedef __int32
|
||||
int32_t,
|
||||
int_least32_t,
|
||||
int_fast8_t,
|
||||
int_fast16_t,
|
||||
int_fast32_t;
|
||||
|
||||
typedef __int64
|
||||
int64_t,
|
||||
intmax_t,
|
||||
int_least64_t,
|
||||
int_fast64_t;
|
||||
|
||||
typedef unsigned __int8
|
||||
uint8_t,
|
||||
uint_least8_t;
|
||||
|
||||
typedef unsigned __int16
|
||||
uint16_t,
|
||||
uint_least16_t;
|
||||
|
||||
typedef unsigned __int32
|
||||
uint32_t,
|
||||
uint_least32_t,
|
||||
uint_fast8_t,
|
||||
uint_fast16_t,
|
||||
uint_fast32_t;
|
||||
|
||||
typedef unsigned __int64
|
||||
uint64_t,
|
||||
uintmax_t,
|
||||
uint_least64_t,
|
||||
uint_fast64_t;
|
||||
|
||||
#ifndef _INTPTR_T_DEFINED
|
||||
#define _INTPTR_T_DEFINED
|
||||
typedef __int32 intptr_t;
|
||||
#endif
|
||||
|
||||
#ifndef _UINTPTR_T_DEFINED
|
||||
#define _UINTPTR_T_DEFINED
|
||||
typedef unsigned __int32 uintptr_t;
|
||||
#endif
|
||||
|
||||
#define INT8_MIN (-127i8 - 1)
|
||||
#define INT16_MIN (-32767i16 - 1)
|
||||
#define INT32_MIN (-2147483647i32 - 1)
|
||||
#define INT64_MIN (-9223372036854775807i64 - 1)
|
||||
#define INT8_MAX 127i8
|
||||
#define INT16_MAX 32767i16
|
||||
#define INT32_MAX 2147483647i32
|
||||
#define INT64_MAX 9223372036854775807i64
|
||||
#define UINT8_MAX 0xffui8
|
||||
#define UINT16_MAX 0xffffui16
|
||||
#define UINT32_MAX 0xffffffffui32
|
||||
#define UINT64_MAX 0xffffffffffffffffui64
|
||||
|
||||
#define INT_LEAST8_MIN INT8_MIN
|
||||
#define INT_LEAST16_MIN INT16_MIN
|
||||
#define INT_LEAST32_MIN INT32_MIN
|
||||
#define INT_LEAST64_MIN INT64_MIN
|
||||
#define INT_LEAST8_MAX INT8_MAX
|
||||
#define INT_LEAST16_MAX INT16_MAX
|
||||
#define INT_LEAST32_MAX INT32_MAX
|
||||
#define INT_LEAST64_MAX INT64_MAX
|
||||
#define UINT_LEAST8_MAX UINT8_MAX
|
||||
#define UINT_LEAST16_MAX UINT16_MAX
|
||||
#define UINT_LEAST32_MAX UINT32_MAX
|
||||
#define UINT_LEAST64_MAX UINT64_MAX
|
||||
|
||||
#define INT_FAST8_MIN INT8_MIN
|
||||
#define INT_FAST16_MIN INT32_MIN
|
||||
#define INT_FAST32_MIN INT32_MIN
|
||||
#define INT_FAST64_MIN INT64_MIN
|
||||
#define INT_FAST8_MAX INT8_MAX
|
||||
#define INT_FAST16_MAX INT32_MAX
|
||||
#define INT_FAST32_MAX INT32_MAX
|
||||
#define INT_FAST64_MAX INT64_MAX
|
||||
#define UINT_FAST8_MAX UINT8_MAX
|
||||
#define UINT_FAST16_MAX UINT32_MAX
|
||||
#define UINT_FAST32_MAX UINT32_MAX
|
||||
#define UINT_FAST64_MAX UINT64_MAX
|
||||
|
||||
#define INTPTR_MIN INT32_MIN
|
||||
#define INTPTR_MAX INT32_MAX
|
||||
#define UINTPTR_MAX UINT32_MAX
|
||||
|
||||
#define INTMAX_MIN INT64_MIN
|
||||
#define INTMAX_MAX INT64_MAX
|
||||
#define UINTMAX_MAX UINT64_MAX
|
||||
|
||||
#define PTRDIFF_MIN INTPTR_MIN
|
||||
#define PTRDIFF_MAX INTPTR_MAX
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
#define SIZE_MAX UINTPTR_MAX
|
||||
#endif
|
||||
|
||||
#define SIG_ATOMIC_MIN INT32_MIN
|
||||
#define SIG_ATOMIC_MAX INT32_MAX
|
||||
|
||||
#define WCHAR_MIN 0x0000
|
||||
#define WCHAR_MAX 0xffff
|
||||
|
||||
#define WINT_MIN 0x0000
|
||||
#define WINT_MAX 0xffff
|
||||
|
||||
#define INT8_C(x) (x)
|
||||
#define INT16_C(x) (x)
|
||||
#define INT32_C(x) (x)
|
||||
#define INT64_C(x) (x ## LL)
|
||||
|
||||
#define UINT8_C(x) (x)
|
||||
#define UINT16_C(x) (x)
|
||||
#define UINT32_C(x) (x ## U)
|
||||
#define UINT64_C(x) (x ## ULL)
|
||||
|
||||
#define INTMAX_C(x) INT64_C(x)
|
||||
#define UINTMAX_C(x) UINT64_C(x)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,79 @@
|
||||
This file credits all the contributors of the Capstone engine project.
|
||||
|
||||
Key developers
|
||||
==============
|
||||
1. Nguyen Anh Quynh <aquynh -at- gmail.com>
|
||||
- Core engine
|
||||
- Bindings: Python, Ruby, OCaml, Java, C#
|
||||
|
||||
2. Tan Sheng Di <shengdi -at- coseinc.com>
|
||||
- Bindings: Ruby
|
||||
|
||||
3. Ben Nagy <ben -at- coseinc.com>
|
||||
- Bindings: Ruby, Go
|
||||
|
||||
4. Dang Hoang Vu <dang.hvu -at- gmail.com>
|
||||
- Bindings: Java
|
||||
|
||||
|
||||
Beta testers (in random order)
|
||||
==============================
|
||||
Pancake
|
||||
Van Hauser
|
||||
FX of Phenoelit
|
||||
The Grugq, The Grugq <-- our hero for submitting the first ever patch!
|
||||
Isaac Dawson, Veracode Inc
|
||||
Patroklos Argyroudis, Census Inc. (http://census-labs.com)
|
||||
Attila Suszter
|
||||
Le Dinh Long
|
||||
Nicolas Ruff
|
||||
Gunther
|
||||
Alex Ionescu, Winsider Seminars & Solutions Inc.
|
||||
Snare
|
||||
Daniel Godas-Lopez
|
||||
Joshua J. Drake
|
||||
Edgar Barbosa
|
||||
Ralf-Philipp Weinmann
|
||||
Hugo Fortier
|
||||
Joxean Koret
|
||||
Bruce Dang
|
||||
Andrew Dunham
|
||||
|
||||
|
||||
Contributors (in no particular order)
|
||||
=====================================
|
||||
(Please let us know if you want to have your name here)
|
||||
|
||||
Ole André Vadla Ravnås (author of the 100th Pull-Request in our Github repo, thanks!)
|
||||
Axel "0vercl0k" Souchet (@0vercl0k) & Alex Ionescu: port to MSVC.
|
||||
Daniel Pistelli: Cmake support.
|
||||
Peter Hlavaty: integrate Capstone for Windows kernel drivers.
|
||||
Guillaume Jeanne: Ocaml binding.
|
||||
Martin Tofall, Obsidium Software: Optimize X86 performance & size + x86 encoding features.
|
||||
David Martínez Moreno & Hilko Bengen: Debian package.
|
||||
Félix Cloutier: Xcode project.
|
||||
Benoit Lecocq: OpenBSD package.
|
||||
Christophe Avoinne (Hlide): Improve memory management for better performance.
|
||||
Michael Cohen & Nguyen Tan Cong: Python module installer.
|
||||
Adel Gadllah, Francisco Alonso & Stefan Cornelius: RPM package.
|
||||
Felix Gröbert (Google): fuzz testing harness.
|
||||
Xipiter LLC: Capstone logo redesigned.
|
||||
Satoshi Tanda: Support Windows kernel driver.
|
||||
Tang Yuhang: cstool.
|
||||
Andrew Dutcher: better Python setup.
|
||||
Ruben Boonen: PowerShell binding.
|
||||
David Zimmer: VB6 binding.
|
||||
Philippe Antoine: Integration with oss-fuzz and various fixes.
|
||||
Bui Dinh Cuong: Explicit registers accessed for Arm64.
|
||||
Vincent Bénony: Explicit registers accessed for X86.
|
||||
Adel Gadllah, Francisco Alonso & Stefan Cornelius: RPM package.
|
||||
Felix Gröbert (Google): fuzz testing harness.
|
||||
Daniel Collin & Nicolas Planel: M68K architecture.
|
||||
Pranith Kumar: Explicit registers accessed for Arm64.
|
||||
Xipiter LLC: Capstone logo redesigned.
|
||||
Satoshi Tanda: Support Windows kernel driver.
|
||||
Koutheir Attouchi: Support for Windows CE.
|
||||
Fotis Loukos: TMS320C64x architecture.
|
||||
Wolfgang Schwotzer: M680X architecture.
|
||||
Philippe Antoine: Integration with oss-fuzz and various fixes.
|
||||
Stephen Eckels (stevemk14ebr): x86 encoding features
|
||||
@@ -0,0 +1,701 @@
|
||||
This file details the changelog of Capstone.
|
||||
|
||||
---------------------------------
|
||||
Version 4.0.1: January 10th, 2019
|
||||
|
||||
|
||||
[ Core ]
|
||||
|
||||
- Fix some issues for packaging (Debian, Gentoo).
|
||||
- Better support for building with Mingw.
|
||||
- cstool has new option -s to turn on skipdata mode.
|
||||
- cstool -v now report build settings of the core.
|
||||
- Add suite/capstone_get_setup.c so users can integrate with their own code
|
||||
to retrieve Capstone settings at build time.
|
||||
|
||||
|
||||
[ Arm ]
|
||||
|
||||
- Fix 4.0 regression: the `tbh [r0, r1, lsl #1]` instruction sets the operand.shift.value back again (see #1317)
|
||||
- Remove ARM_REG_PC group for BX instruction.
|
||||
|
||||
|
||||
[ X86 ]
|
||||
|
||||
- Fix: endbr32 and endbr64 instructions are now properly decoded in both CS_MODE_32 and CS_MODE_64 (#1129)
|
||||
|
||||
|
||||
[ M680X ]
|
||||
|
||||
- Fix some issues reported by clang-analyzer (#1329).
|
||||
|
||||
|
||||
[ Python ]
|
||||
|
||||
- Fix skipdata setup.
|
||||
- Add getter/setter for skipdata_mnem, skipdata_callback.
|
||||
|
||||
|
||||
---------------------------------
|
||||
Version 4.0: December 18th, 2018
|
||||
|
||||
|
||||
[ Core ]
|
||||
|
||||
- New APIs: cs_regs_access()
|
||||
- Add new options for cs_option(): CS_OPT_MNEMONIC & CS_OPT_UNSIGNED & CS_OPT_SYNTAX_MASM.
|
||||
- Various updates & bugfixes for all architectures.
|
||||
- Add 4 new architectures: EVM, M68K, M680X & TMS320C64x.
|
||||
- Add new group types: CS_GRP_PRIVILEGE & CS_GRP_BRANCH_RELATIVE.
|
||||
- Add new error types: CS_ERR_X86_MASM.
|
||||
|
||||
|
||||
[ X86 ]
|
||||
|
||||
- Add XOP code condition type in x86_xop_cc.
|
||||
- Add some info on encoding to cs_x86 in cs_x86_encoding.
|
||||
- Add register flags update in cs_x86.{eflags, fpu_flags}
|
||||
- Change cs_x86.disp type from int32_t to int64_t.
|
||||
- Add new groups: X86_GRP_VM & X86_GRP_FPU.
|
||||
- Lots of new instructions (AVX)
|
||||
|
||||
|
||||
[ ARM64 ]
|
||||
|
||||
- Add instruction ARM64_INS_NEGS & ARM64_INS_NGCS.
|
||||
|
||||
|
||||
[ Mips ]
|
||||
|
||||
- Add mode CS_MODE_MIPS2.
|
||||
|
||||
|
||||
[ PPC ]
|
||||
|
||||
- Change cs_ppc_op.imm type from int32_t to int64_t.
|
||||
- Add new groups: PPC_GRP_ICBT, PPC_GRP_P8ALTIVEC, PPC_GRP_P8VECTOR & PPC_GRP_QPX.
|
||||
- Lots of new instructions (QPX among them)
|
||||
|
||||
|
||||
[ Sparc ]
|
||||
|
||||
- Change cs_sparc_op.imm type from int32_t to int64_t.
|
||||
|
||||
|
||||
[ Binding ]
|
||||
|
||||
- New bindings: PowerShell & VB6
|
||||
|
||||
|
||||
---------------------------------
|
||||
Version 3.0.5: July 18th, 2018
|
||||
|
||||
|
||||
[ Core ]
|
||||
|
||||
- Fix the include path for Android builds when building cstool.
|
||||
- Add posibility to disable universal build for Mac OS.
|
||||
- cstool: Separate instruction bytes by spaces.
|
||||
- Fix code path of pkg-config in Cmake.
|
||||
- Update XCode project for XCode 9.1.
|
||||
- Add Cortex-M support to cstool.
|
||||
- Cmake forces to be build using MT with MSVC.
|
||||
- Better support for Mac OS kernel.
|
||||
|
||||
|
||||
[ X86 ]
|
||||
|
||||
- Fix some issues in handling EVEX & VEX3 instructions.
|
||||
- Fix immediate operand for AND instruction in ATT mode.
|
||||
- Fix ATT syntax when imm operand is 0.
|
||||
- Better handle XACQUIRE/XRELEASE.
|
||||
- Fix imm operand of RETF.
|
||||
|
||||
|
||||
[ ARM ]
|
||||
|
||||
- Fix an integer overlow bug.
|
||||
|
||||
|
||||
[ ARM64 ]
|
||||
|
||||
- Bug fix for incorrect operand type in certain load/store instructions.
|
||||
|
||||
|
||||
[ Mips ]
|
||||
|
||||
- Mode CS_MODE_MIPS32R6 automatically sets CS_MODE_32
|
||||
|
||||
|
||||
[ PPC ]
|
||||
|
||||
- Fix endian check.
|
||||
|
||||
|
||||
[ Sparc ]
|
||||
|
||||
- Fix an integer overlow bug.
|
||||
|
||||
|
||||
[ SystemZ ]
|
||||
|
||||
- Fix an integer overlow bug.
|
||||
|
||||
|
||||
[ Python binding ]
|
||||
|
||||
- Raise error on accessing irrelevant data fields if skipdata & detail modes are enable.
|
||||
|
||||
|
||||
---------------------------------
|
||||
Version 3.0.5-rc3: July 31st, 2017
|
||||
|
||||
|
||||
[ Core ]
|
||||
|
||||
- Fix compilation for MacOS kernel extension
|
||||
- cstool to support armbe and arm64be modes
|
||||
- Add nmake.bat for Windows build
|
||||
- Fix an integer overflow for Windows kernel driver
|
||||
- Support to embedded Capstone into MacOS kernel
|
||||
- cstool: fix mips64 mode
|
||||
- Fix a compiling error in MS Visual Studio 2015
|
||||
- Install pkgconfig file with CMake build
|
||||
- Fix SOVERSION property of CMake build
|
||||
- Properly handle switching to Endian mode at run-time for Arm, Arm64, Mips & Sparc
|
||||
- Fix MingW build
|
||||
- Better handle CMake installation for Linux 64bit
|
||||
|
||||
|
||||
[ X86 ]
|
||||
|
||||
- Support BND prefix of Intel MPX extension
|
||||
- Correct operand size for CALL/JMP in 64bit mode with prefix 0x66
|
||||
- LOCK NOP is a valid instruction
|
||||
- Fix ATT syntax for instruction with zero offset segment register
|
||||
- LES/LDS are invalid in 64bit mode
|
||||
- Fix number of operands for some MOV instructions
|
||||
|
||||
|
||||
[ ARM ]
|
||||
|
||||
- Fix POP reg to update SP register
|
||||
- Update flags for UADD8 instruction
|
||||
|
||||
|
||||
[ ARM64 ]
|
||||
|
||||
- Better performance with new lookup table
|
||||
- Handle system registers added in ARMv8.1/2
|
||||
|
||||
|
||||
[ Java binding ]
|
||||
|
||||
- Better handle input with invalid code
|
||||
|
||||
|
||||
[ Visual Basic binding ]
|
||||
|
||||
- New binding
|
||||
|
||||
---------------------------------
|
||||
Version 3.0.5-rc2: March 2nd, 2017
|
||||
|
||||
|
||||
[ Core ]
|
||||
|
||||
- Fix build for Visual Studio 2012
|
||||
- Fix X86_REL_ADDR macro
|
||||
- Add CS_VERSION_MAJOR, CS_VERSION_MINOR, CS_VERSION_EXTRA
|
||||
- Better support for embedding Capstone into Windows kernel drivers
|
||||
- Support to embedded Capstone into MacOS kernel
|
||||
- Support MacOS 10.11 and up
|
||||
- Better support for Cygwin
|
||||
- Support build packages for FreeBSD & DragonflyBSD
|
||||
- Add a command-line tool "cstool"
|
||||
- Properly handle switching to Endian mode at run-time for Arm, Arm64, Mips & Sparc
|
||||
|
||||
|
||||
[ X86 ]
|
||||
|
||||
- Some random 16-bit code can be handled wrongly.
|
||||
- Remove abundant operand type X86_OP_FP
|
||||
- Fix instructions MOVQ, LOOP, LOOPE, LOOPNE, CALL/JMP rel16, REPNE LODSD, MOV *AX, MOFFS, FAR JMP/CALL
|
||||
- Add X86_REG_EFLAGS for STC and STD
|
||||
- Fix instruction attributes for SYSEXIT, MOVW, ROL, LGS, SLDT
|
||||
- Rename registers ST0-ST7 to be consistent with asm output
|
||||
|
||||
|
||||
[ ARM ]
|
||||
|
||||
- Properly handle IT instruction
|
||||
- Fix LDRSB
|
||||
- Fix writeback for LDR
|
||||
- Fix Thumb BigEndian setup
|
||||
|
||||
|
||||
[ ARM64 ]
|
||||
|
||||
- Fix arith extender
|
||||
- Fix writeback for LDR
|
||||
- Rename enum arm64_mrs_reg to arm64_sysreg
|
||||
|
||||
|
||||
[ PowerPC ]
|
||||
|
||||
- Print 0 offset for memory operand
|
||||
|
||||
|
||||
[ Sparc ]
|
||||
|
||||
- Fix POPC instruction
|
||||
|
||||
|
||||
[ Python binding ]
|
||||
|
||||
- Better PyPy support
|
||||
- Add __version__
|
||||
- Better support for Python 3
|
||||
- Fix CS_SKIPDATA_CALLBACK prototype
|
||||
- Cast skipdata function inside binding to simplify the API
|
||||
|
||||
|
||||
[ Java binding ]
|
||||
|
||||
- Better handle input with invalid code
|
||||
|
||||
|
||||
[ PowerShell ]
|
||||
|
||||
- New binding
|
||||
|
||||
---------------------------------
|
||||
Version 3.0.4: July 15th, 2015
|
||||
|
||||
|
||||
[ Library ]
|
||||
|
||||
- Improve cross-compile for Android using Android NDK.
|
||||
- Support cross-compile for AArch64 Android (with Linux GCC).
|
||||
- Removed osxkernel_inttypes.h that is incompatible with BSD license.
|
||||
- Make it possible to compile with CC having a space inside (like "ccache gcc").
|
||||
|
||||
|
||||
[ X86 ]
|
||||
|
||||
- Fix a null pointer dereference bug on handling code with special prefixes.
|
||||
- Properly handle AL/AX/EAX operand for OUT instruction in AT&T syntax.
|
||||
- Print immediate operand in positive form in some algorithm instructions.
|
||||
- Properly decode some SSE instructions.
|
||||
|
||||
|
||||
[ PowerPC ]
|
||||
|
||||
- Fixed a memory corruption bug.
|
||||
- Fixed a memory corruption bug for the engine built in DIET mode.
|
||||
|
||||
|
||||
[ Mips ]
|
||||
|
||||
- Fixed instruction ID of SUBU instruction.
|
||||
- Fixed a memory corruption bug.
|
||||
|
||||
|
||||
[ Arm ]
|
||||
|
||||
- Fixed a memory corruption bug on IT instruction.
|
||||
|
||||
|
||||
[ XCore ]
|
||||
|
||||
- Fixed a memory corruption bug when instruction has a memory operand.
|
||||
|
||||
|
||||
[ Python ]
|
||||
|
||||
- Support Virtualenv.
|
||||
- setup.py supports option --user if not in a virtualenv to allow for local usage.
|
||||
- Properly handle the destruction of Cs object in the case the shared library
|
||||
was already unloaded.
|
||||
|
||||
---------------------------------
|
||||
Version 3.0.3: May 08th, 2015
|
||||
|
||||
|
||||
[ Library ]
|
||||
|
||||
- Support to embed into Mac OS X kernel extensions.
|
||||
- Now it is possible to compile Capstone with older C compilers, such as
|
||||
GCC 4.8 on Ubuntu 12.04.
|
||||
- Add "test_iter" to MSVC project.
|
||||
|
||||
|
||||
[ X86 ]
|
||||
|
||||
- All shifted instructions SHL, SHR, SAL, SAR, RCL, RCR, ROL & ROR now support
|
||||
$1 as first operand in *AT&T* syntax (so we have "rcll $1, %edx" instead of
|
||||
"rcll %edx").
|
||||
- CMPXCHG16B is a valid instruction with LOCK prefix.
|
||||
- Fixed a segfault on the input of 0xF3.
|
||||
|
||||
|
||||
[ Arm ]
|
||||
|
||||
- BLX instruction modifies PC & LR registers.
|
||||
|
||||
|
||||
[ Sparc ]
|
||||
|
||||
- Improved displacement decoding for sparc banching instructions.
|
||||
|
||||
|
||||
[ Python binding ]
|
||||
|
||||
- Fix for Cython so it can properly initialize.
|
||||
- X86Op.avx_zero_mask now has c_bool type, but not c_uint8 type.
|
||||
- Properly support compile with Cygwin & install binding (setup.py).
|
||||
|
||||
---------------------------------
|
||||
Version 3.0.2: March 11th, 2015
|
||||
|
||||
|
||||
[ Library ]
|
||||
|
||||
- On *nix, only export symbols that are part of the API (instead of all
|
||||
the internal symbols).
|
||||
|
||||
|
||||
[ X86 ]
|
||||
|
||||
- Do not consider 0xF2 as REPNE prefix if it is a part of instruction encoding.
|
||||
- Fix implicit registers read/written & instruction groups of some instructions.
|
||||
- More flexible on the order of prefixes, so better handle some tricky
|
||||
instructions.
|
||||
- REPNE prefix can go with STOS & MOVS instructions.
|
||||
- Fix a compilation bug for X86_REDUCE mode.
|
||||
- Fix operand size of instructions with operand PTR []
|
||||
|
||||
|
||||
[ Arm ]
|
||||
|
||||
- Fix a bug where arm_op_mem.disp is wrongly calculated (in DETAIL mode).
|
||||
- Fix a bug on handling the If-Then block.
|
||||
|
||||
|
||||
[ Mips ]
|
||||
|
||||
- Sanity check for the input size for MIPS64 mode.
|
||||
|
||||
|
||||
[ MSVC ]
|
||||
|
||||
- Compile capstone.dll with static runtime MSVCR built in.
|
||||
|
||||
|
||||
[ Python binding ]
|
||||
|
||||
- Fix a compiling issue of Cython binding with gcc 4.9.
|
||||
|
||||
---------------------------------
|
||||
Version 3.0.1: February 03rd, 2015
|
||||
|
||||
[ X86 ]
|
||||
|
||||
- Properly handle LOCK, REP, REPE & REPNE prefixes.
|
||||
- Handle undocumented immediates for SSE's (V)CMPPS/PD/SS/SD instructions.
|
||||
- Print LJUMP/LCALL without * as prefix for Intel syntax.
|
||||
- Handle REX prefix properly for segment/MMX related instructions (x86_64).
|
||||
- Instruction with length > 15 is consider invalid.
|
||||
- Handle some tricky encodings for instructions MOVSXD, FXCH, FCOM, FCOMP,
|
||||
FSTP, FSTPNCE, NOP.
|
||||
- Handle some tricky code for some X86_64 instructions with REX prefix.
|
||||
- Add missing operands in detail mode for PUSH , POP , IN/OUT reg, reg
|
||||
- MOV32ms & MOV32sm should reference word rather than dword.
|
||||
|
||||
|
||||
[ Arm64 ]
|
||||
|
||||
- BL & BLR instructions do not read SP register.
|
||||
- Print absolute (rather than relative) address for instructions B, BL,
|
||||
CBNZ, ADR.
|
||||
|
||||
|
||||
[ Arm ]
|
||||
|
||||
- Instructions ADC & SBC do not update flags.
|
||||
- BL & BLX do not read SP, but PC register.
|
||||
- Alias LDR instruction with operands [sp], 4 to POP.
|
||||
- Print immediate operand of MVN instruction in positive hexadecimal form.
|
||||
|
||||
|
||||
[ PowerPC ]
|
||||
|
||||
- Fix some compilation bugs when DIET mode is enable.
|
||||
- Populate SLWI/SRWI instruction details with SH operand.
|
||||
|
||||
|
||||
[ Python binding ]
|
||||
|
||||
- Fix a Cython bug when CsInsn.bytes returns a shorten array of bytes.
|
||||
- Fixed a memory leak for Cython disasm functions when we immaturely quit
|
||||
the enumeration of disassembled instructions.
|
||||
- Fix a NULL memory access issue when SKIPDATA & Detail modes are enable
|
||||
at the same time.
|
||||
- Fix a memory leaking bug when when we stop enumeration over the disassembled
|
||||
instructions prematurely.
|
||||
- Export generic operand types & groups (CS_OP_xxx & CS_GRP_xxx).
|
||||
|
||||
---------------------------------
|
||||
Version 3.0: November 19th, 2014
|
||||
|
||||
[ API ]
|
||||
|
||||
- New API: cs_disasm_iter & cs_malloc. See docs/README for tutorials.
|
||||
- Renamed cs_disasm_ex to cs_disasm (cs_disasm_ex is still supported, but
|
||||
marked obsolete to be removed in future)
|
||||
- Support SKIPDATA mode, so Capstone can jump over unknown data and keep going
|
||||
from the next legitimate instruction. See docs/README for tutorials.
|
||||
- More details provided in cs_detail struct for all architectures.
|
||||
- API version was bumped to 3.0.
|
||||
|
||||
|
||||
[ Bindings ]
|
||||
|
||||
- Python binding supports Python3 (besides Python2).
|
||||
- Support Ocaml binding.
|
||||
- Java: add close() method to be used to deinitialize a Capstone object when
|
||||
no longer use it.
|
||||
|
||||
|
||||
[ Architectures ]
|
||||
|
||||
- New architectures: Sparc, SystemZ & XCore.
|
||||
- Important bugfixes for Arm, Arm64, Mips, PowerPC & X86.
|
||||
- Support more instructions for Arm, Arm64, Mips, PowerPC & X86.
|
||||
- Always expose absolute addresses rather than relative addresses (Arm, Arm64,
|
||||
Mips, PPC, Sparc, X86).
|
||||
- Use common instruction operand types REG, IMM, MEM & FP across all
|
||||
architectures (to enable cross-architecture analysis).
|
||||
- Use common instruction group types across all architectures (to enable
|
||||
cross-architecture analysis).
|
||||
|
||||
|
||||
[ X86 ]
|
||||
|
||||
- X86 engine is mature & handles all the malware tricks (that we are aware of).
|
||||
- Added a lot of new instructions (such as AVX512, 3DNow, etc).
|
||||
- Add prefix symbols X86_PREFIX_REP/REPNE/LOCK/CS/DS/SS/FS/GS/ES/OPSIZE/ADDRSIZE.
|
||||
- Print immediate in positive form & hexadecimal for AND/OR/XOR instructions.
|
||||
- More friendly disassembly for JMP16i (in the form segment:offset)
|
||||
|
||||
|
||||
[ Mips ]
|
||||
|
||||
- Engine added supports for new hardware modes: Mips32R6 (CS_MODE_MIPS32R6) &
|
||||
MipsGP64 (CS_MODE_MIPSGP64).
|
||||
- Removed the ABI-only mode CS_MODE_N64.
|
||||
- New modes CS_MODE_MIPS32 & CS_MODE_MIPS64 (to use instead of CS_MODE_32 &
|
||||
CS_MODE_64).
|
||||
|
||||
|
||||
[ ARM ]
|
||||
|
||||
- Support new mode CS_MODE_V8 for Armv8 A32 encodings.
|
||||
- Print immediate in positive form & hexadecimal for AND/ORR/EOR/BIC instructions
|
||||
|
||||
|
||||
[ ARM64 ]
|
||||
|
||||
- Print immediate in hexadecimal for AND/ORR/EOR/TST instructions.
|
||||
|
||||
|
||||
[ PowerPC ]
|
||||
|
||||
- Do not print a dot in front of absolute address.
|
||||
|
||||
|
||||
[ Other features ]
|
||||
|
||||
- Support for Microsoft Visual Studio (so enable Windows native compilation).
|
||||
- Support CMake compilation.
|
||||
- Cross-compile for Android.
|
||||
- Build libraries/tests using XCode project
|
||||
- Much faster, while consuming less memory for all architectures.
|
||||
|
||||
---------------------------------
|
||||
Version 2.1.2: April 3rd, 2014
|
||||
|
||||
This is a stable release to fix some bugs deep in the core. There is no update
|
||||
to any architectures or bindings, so bindings version 2.1 can be used with this
|
||||
version 2.1.2 just fine.
|
||||
|
||||
[ Core changes]
|
||||
|
||||
- Support cross-compilation for all iDevices (iPhone/iPad/iPod).
|
||||
- X86: do not print memory offset in negative form.
|
||||
- Fix a bug in X86 when Capstone cannot handle short instruction.
|
||||
- Print negative number above -9 without prefix 0x (arm64, mips, arm).
|
||||
- Correct the SONAME setup for library versioning (Linux, *BSD, Solaris).
|
||||
- Set library versioning for dylib of OSX.
|
||||
|
||||
---------------------------------
|
||||
Version 2.1.1: March 13th, 2014
|
||||
|
||||
This is a stable release to fix some bugs deep in the core. There is no update
|
||||
to any architectures or bindings, so bindings version 2.1 can be used with this
|
||||
version 2.1.1 just fine.
|
||||
|
||||
[ Core changes]
|
||||
|
||||
- Fix a buffer overflow bug in Thumb mode (ARM). Some special input can
|
||||
trigger this flaw.
|
||||
- Fix a crash issue when embedding Capstone into OSX kernel. This should
|
||||
also enable Capstone to be embedded into other systems with limited stack
|
||||
memory size such as Linux kernel or some firmwares.
|
||||
- Use a proper SONAME for library versioning (Linux).
|
||||
|
||||
---------------------------------
|
||||
Version 2.1: March 5th, 2014
|
||||
|
||||
[ API changes ]
|
||||
|
||||
- API version has been bumped to 2.1.
|
||||
- Change prototype of cs_close() to be able to invalidate closed handle.
|
||||
See http://capstone-engine.org/version_2.1_API.html for more information.
|
||||
- Extend cs_support() to handle more query types, not only about supported
|
||||
architectures. This change is backward compatible, however, so existent code
|
||||
do not need to be modified to support this.
|
||||
- New query type CS_SUPPORT_DIET for cs_support() to ask about diet status of
|
||||
the engine.
|
||||
- New error code CS_ERR_DIET to report errors about newly added diet mode.
|
||||
- New error code CS_ERR_VERSION to report issue of incompatible versions between
|
||||
bindings & core engine.
|
||||
|
||||
|
||||
[ Core changes ]
|
||||
|
||||
- On memory usage, Capstone uses about 40% less memory, while still faster
|
||||
than version 2.0.
|
||||
- All architectures are much smaller: binaries size reduce at least 30%.
|
||||
Especially, X86-only binary reduces from 1.9MB to just 720KB.
|
||||
- Support "diet" mode, in which engine size is further reduced (by around 40%)
|
||||
for embedding purpose. The price to pay is that we have to sacrifice some
|
||||
non-critical data fields. See http://capstone-engine.org/diet.html for more
|
||||
details.
|
||||
|
||||
|
||||
[ Architectures ]
|
||||
|
||||
- Update all 5 architectures to fix bugs.
|
||||
- PowerPC:
|
||||
- New instructions: FMR & MSYNC.
|
||||
- Mips:
|
||||
- New instruction: DLSA
|
||||
- X86:
|
||||
- Properly handle AVX-512 instructions.
|
||||
- New instructions: PSETPM, SALC, INT1, GETSEC.
|
||||
- Fix some memory leaking issues in case of prefixed instructions such
|
||||
as LOCK, REP, REPNE.
|
||||
|
||||
|
||||
[ Python binding ]
|
||||
|
||||
- Verify the core version at initialization time. Refuse to run if its version
|
||||
is different from the core's version.
|
||||
- New API disasm_lite() added to Cs class. This light API only returns tuples of
|
||||
(address, size, mnemonic, op_str), rather than list of CsInsn objects. This
|
||||
improves performance by around 30% in some benchmarks.
|
||||
- New API version_bind() returns binding's version, which might differ from
|
||||
the core's API version if the binding is out-of-date.
|
||||
- New API debug() returns information on Cython support, diet status & archs
|
||||
compiled in.
|
||||
- Fixed some memory leaking bugs for Cython binding.
|
||||
- Fix a bug crashing Cython code when accessing @regs_read/regs_write/groups.
|
||||
- Support diet mode.
|
||||
|
||||
|
||||
[ Java binding ]
|
||||
|
||||
- Fix some memory leaking bugs.
|
||||
- New API version() returns combined version.
|
||||
- Support diet mode.
|
||||
- Better support for detail option.
|
||||
|
||||
|
||||
[ Miscellaneous ]
|
||||
|
||||
- make.sh now can uninstall the core engine. This is done with:
|
||||
|
||||
$ sudo ./make.sh uninstall
|
||||
|
||||
----------------------------------
|
||||
Version 2.0: January 22nd, 2014
|
||||
|
||||
Release 2.0 deprecates verison 1.0 and brings a lot of crucial changes.
|
||||
|
||||
[ API changes ]
|
||||
|
||||
- API version has been bumped to 2.0 (see cs_version() API)
|
||||
- New API cs_strerror(errno) returns a string describing error code given
|
||||
in its only argument.
|
||||
- cs_version() now returns combined version encoding both major & minor versions.
|
||||
- New option CS_OPT_MODE allows to change engine’s mode at run-time with
|
||||
cs_option().
|
||||
- New option CS_OPT_MEM allows to specify user-defined functions for dynamically
|
||||
memory management used internally by Capstone. This is useful to embed Capstone
|
||||
into special environments such as kernel or firware.
|
||||
- New API cs_support() can be used to check if this lib supports a particular
|
||||
architecture (this is necessary since we now allow to choose which architectures
|
||||
to compile in).
|
||||
- The detail option is OFF by default now. To get detail information, it should be
|
||||
explicitly turned ON. The details then can be accessed using cs_insn.detail
|
||||
pointer (to newly added structure cs_detail)
|
||||
|
||||
|
||||
[ Core changes ]
|
||||
|
||||
- On memory usage, Capstone uses much less memory, but a lot faster now.
|
||||
- User now can choose which architectures to be supported by modifying config.mk
|
||||
before compiling/installing.
|
||||
|
||||
|
||||
[ Architectures ]
|
||||
|
||||
- Arm
|
||||
- Support Big-Endian mode (besides Little-Endian mode).
|
||||
- Support friendly register, so instead of output sub "r12,r11,0x14",
|
||||
we have "sub ip,fp,0x14".
|
||||
- Arm64: support Big-Endian mode (besides Little-Endian mode).
|
||||
- PowerPC: newly added.
|
||||
- Mips: support friendly register, so instead of output "srl $2,$1,0x1f",
|
||||
we have "srl $v0,$at,0x1f".
|
||||
- X86: bug fixes.
|
||||
|
||||
|
||||
[ Python binding ]
|
||||
|
||||
- Python binding is vastly improved in performance: around 3 ~ 4 times faster
|
||||
than in 1.0.
|
||||
- Cython support has been added, which can further speed up over the default
|
||||
pure Python binding (up to 30% in some cases)
|
||||
- Function cs_disasm_quick() & Cs.disasm() now use generator (rather than a list)
|
||||
to return succesfully disassembled instructions. This improves the performance
|
||||
and reduces memory usage.
|
||||
|
||||
|
||||
[ Java binding ]
|
||||
|
||||
- Better performance & bug fixes.
|
||||
|
||||
|
||||
[ Miscellaneous ]
|
||||
|
||||
- Fixed some installation issues with Gentoo Linux.
|
||||
- Capstone now can easily compile/install on all *nix, including Linux, OSX,
|
||||
{Net, Free, Open}BSD & Solaris.
|
||||
|
||||
----------------------------------
|
||||
[Version 1.0]: December 18th, 2013
|
||||
|
||||
- Initial public release.
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
This is the software license for Capstone disassembly framework.
|
||||
Capstone has been designed & implemented by Nguyen Anh Quynh <aquynh@gmail.com>
|
||||
|
||||
See http://www.capstone-engine.org for further information.
|
||||
|
||||
Copyright (c) 2013, COSEINC.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of the developer(s) nor the names of its
|
||||
contributors may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -0,0 +1,71 @@
|
||||
==============================================================================
|
||||
LLVM Release License
|
||||
==============================================================================
|
||||
University of Illinois/NCSA
|
||||
Open Source License
|
||||
|
||||
Copyright (c) 2003-2013 University of Illinois at Urbana-Champaign.
|
||||
All rights reserved.
|
||||
|
||||
Developed by:
|
||||
|
||||
LLVM Team
|
||||
|
||||
University of Illinois at Urbana-Champaign
|
||||
|
||||
http://llvm.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal with
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimers.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimers in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the names of the LLVM Team, University of Illinois at
|
||||
Urbana-Champaign, nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this Software without specific
|
||||
prior written permission.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
|
||||
SOFTWARE.
|
||||
|
||||
==============================================================================
|
||||
Copyrights and Licenses for Third Party Software Distributed with LLVM:
|
||||
==============================================================================
|
||||
The LLVM software contains code written by third parties. Such software will
|
||||
have its own individual LICENSE.TXT file in the directory in which it appears.
|
||||
This file will describe the copyrights, license, and restrictions which apply
|
||||
to that code.
|
||||
|
||||
The disclaimer of warranty in the University of Illinois Open Source License
|
||||
applies to all code in the LLVM Distribution, and nothing in any of the
|
||||
other licenses gives permission to use the names of the LLVM Team or the
|
||||
University of Illinois to endorse or promote products derived from this
|
||||
Software.
|
||||
|
||||
The following pieces of software have additional or alternate copyrights,
|
||||
licenses, and/or restrictions:
|
||||
|
||||
Program Directory
|
||||
------- ---------
|
||||
Autoconf llvm/autoconf
|
||||
llvm/projects/ModuleMaker/autoconf
|
||||
llvm/projects/sample/autoconf
|
||||
Google Test llvm/utils/unittest/googletest
|
||||
OpenBSD regex llvm/lib/Support/{reg*, COPYRIGHT.regex}
|
||||
pyyaml tests llvm/test/YAMLParser/{*.data, LICENSE.TXT}
|
||||
ARM contributions llvm/lib/Target/ARM/LICENSE.TXT
|
||||
md5 contributions llvm/lib/Support/MD5.cpp llvm/include/llvm/Support/MD5.h
|
||||
@@ -0,0 +1,65 @@
|
||||
Capstone Engine
|
||||
===============
|
||||
|
||||
[](https://travis-ci.org/aquynh/capstone)
|
||||
[](https://ci.appveyor.com/project/aquynh/capstone/branch/next)
|
||||
|
||||
Capstone is a disassembly framework with the target of becoming the ultimate
|
||||
disasm engine for binary analysis and reversing in the security community.
|
||||
|
||||
Created by Nguyen Anh Quynh, then developed and maintained by a small community,
|
||||
Capstone offers some unparalleled features:
|
||||
|
||||
- Support multiple hardware architectures: ARM, ARM64 (ARMv8), Ethereum VM, M68K,
|
||||
Mips, PPC, Sparc, SystemZ, TMS320C64X, M680X, XCore and X86 (including X86_64).
|
||||
|
||||
- Having clean/simple/lightweight/intuitive architecture-neutral API.
|
||||
|
||||
- Provide details on disassembled instruction (called “decomposer” by others).
|
||||
|
||||
- Provide semantics of the disassembled instruction, such as list of implicit
|
||||
registers read & written.
|
||||
|
||||
- Implemented in pure C language, with lightweight bindings for D, Clojure, F#,
|
||||
Common Lisp, Visual Basic, PHP, PowerShell, Emacs, Haskell, Perl, Python,
|
||||
Ruby, C#, NodeJS, Java, GO, C++, OCaml, Lua, Rust, Delphi, Free Pascal & Vala
|
||||
ready either in main code, or provided externally by the community).
|
||||
|
||||
- Native support for all popular platforms: Windows, Mac OSX, iOS, Android,
|
||||
Linux, \*BSD, Solaris, etc.
|
||||
|
||||
- Thread-safe by design.
|
||||
|
||||
- Special support for embedding into firmware or OS kernel.
|
||||
|
||||
- High performance & suitable for malware analysis (capable of handling various
|
||||
X86 malware tricks).
|
||||
|
||||
- Distributed under the open source BSD license.
|
||||
|
||||
Further information is available at http://www.capstone-engine.org
|
||||
|
||||
|
||||
Compile
|
||||
-------
|
||||
|
||||
See COMPILE.TXT file for how to compile and install Capstone.
|
||||
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
See docs/README for how to customize & program your own tools with Capstone.
|
||||
|
||||
|
||||
Hack
|
||||
----
|
||||
|
||||
See HACK.TXT file for the structure of the source code.
|
||||
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
This project is released under the BSD license. If you redistribute the binary
|
||||
or source code of Capstone, please attach file LICENSE.TXT with your products.
|
||||
@@ -0,0 +1,20 @@
|
||||
* Version 4.0.1 - January 10th, 2019
|
||||
|
||||
Release 4.0.1 was sponsored by the following companies (in no particular order).
|
||||
|
||||
- NowSecure: https://www.nowsecure.com
|
||||
- Verichains: https://verichains.io
|
||||
- Vsec: https://vsec.com.vn
|
||||
|
||||
-----------------------------------
|
||||
* Version 4.0 - December 18th, 2018
|
||||
|
||||
Capstone 4.0 version marks 5 years of the project!
|
||||
This release was sponsored by the following companies (in no particular order).
|
||||
|
||||
- Thinkst Canary: https://canary.tools
|
||||
- NowSecure: https://www.nowsecure.com
|
||||
- ECQ: https://e-cq.net
|
||||
- Senrio: https://senr.io
|
||||
- GracefulBits: https://gracefulbits.com
|
||||
- Catena Cyber: https://catenacyber.fr
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,937 @@
|
||||
#ifndef CAPSTONE_ARM_H
|
||||
#define CAPSTONE_ARM_H
|
||||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
/// ARM shift type
|
||||
typedef enum arm_shifter {
|
||||
ARM_SFT_INVALID = 0,
|
||||
ARM_SFT_ASR, ///< shift with immediate const
|
||||
ARM_SFT_LSL, ///< shift with immediate const
|
||||
ARM_SFT_LSR, ///< shift with immediate const
|
||||
ARM_SFT_ROR, ///< shift with immediate const
|
||||
ARM_SFT_RRX, ///< shift with immediate const
|
||||
ARM_SFT_ASR_REG, ///< shift with register
|
||||
ARM_SFT_LSL_REG, ///< shift with register
|
||||
ARM_SFT_LSR_REG, ///< shift with register
|
||||
ARM_SFT_ROR_REG, ///< shift with register
|
||||
ARM_SFT_RRX_REG, ///< shift with register
|
||||
} arm_shifter;
|
||||
|
||||
/// ARM condition code
|
||||
typedef enum arm_cc {
|
||||
ARM_CC_INVALID = 0,
|
||||
ARM_CC_EQ, ///< Equal Equal
|
||||
ARM_CC_NE, ///< Not equal Not equal, or unordered
|
||||
ARM_CC_HS, ///< Carry set >, ==, or unordered
|
||||
ARM_CC_LO, ///< Carry clear Less than
|
||||
ARM_CC_MI, ///< Minus, negative Less than
|
||||
ARM_CC_PL, ///< Plus, positive or zero >, ==, or unordered
|
||||
ARM_CC_VS, ///< Overflow Unordered
|
||||
ARM_CC_VC, ///< No overflow Not unordered
|
||||
ARM_CC_HI, ///< Unsigned higher Greater than, or unordered
|
||||
ARM_CC_LS, ///< Unsigned lower or same Less than or equal
|
||||
ARM_CC_GE, ///< Greater than or equal Greater than or equal
|
||||
ARM_CC_LT, ///< Less than Less than, or unordered
|
||||
ARM_CC_GT, ///< Greater than Greater than
|
||||
ARM_CC_LE, ///< Less than or equal <, ==, or unordered
|
||||
ARM_CC_AL ///< Always (unconditional) Always (unconditional)
|
||||
} arm_cc;
|
||||
|
||||
typedef enum arm_sysreg {
|
||||
/// Special registers for MSR
|
||||
ARM_SYSREG_INVALID = 0,
|
||||
|
||||
// SPSR* registers can be OR combined
|
||||
ARM_SYSREG_SPSR_C = 1,
|
||||
ARM_SYSREG_SPSR_X = 2,
|
||||
ARM_SYSREG_SPSR_S = 4,
|
||||
ARM_SYSREG_SPSR_F = 8,
|
||||
|
||||
// CPSR* registers can be OR combined
|
||||
ARM_SYSREG_CPSR_C = 16,
|
||||
ARM_SYSREG_CPSR_X = 32,
|
||||
ARM_SYSREG_CPSR_S = 64,
|
||||
ARM_SYSREG_CPSR_F = 128,
|
||||
|
||||
// independent registers
|
||||
ARM_SYSREG_APSR = 256,
|
||||
ARM_SYSREG_APSR_G,
|
||||
ARM_SYSREG_APSR_NZCVQ,
|
||||
ARM_SYSREG_APSR_NZCVQG,
|
||||
|
||||
ARM_SYSREG_IAPSR,
|
||||
ARM_SYSREG_IAPSR_G,
|
||||
ARM_SYSREG_IAPSR_NZCVQG,
|
||||
ARM_SYSREG_IAPSR_NZCVQ,
|
||||
|
||||
ARM_SYSREG_EAPSR,
|
||||
ARM_SYSREG_EAPSR_G,
|
||||
ARM_SYSREG_EAPSR_NZCVQG,
|
||||
ARM_SYSREG_EAPSR_NZCVQ,
|
||||
|
||||
ARM_SYSREG_XPSR,
|
||||
ARM_SYSREG_XPSR_G,
|
||||
ARM_SYSREG_XPSR_NZCVQG,
|
||||
ARM_SYSREG_XPSR_NZCVQ,
|
||||
|
||||
ARM_SYSREG_IPSR,
|
||||
ARM_SYSREG_EPSR,
|
||||
ARM_SYSREG_IEPSR,
|
||||
|
||||
ARM_SYSREG_MSP,
|
||||
ARM_SYSREG_PSP,
|
||||
ARM_SYSREG_PRIMASK,
|
||||
ARM_SYSREG_BASEPRI,
|
||||
ARM_SYSREG_BASEPRI_MAX,
|
||||
ARM_SYSREG_FAULTMASK,
|
||||
ARM_SYSREG_CONTROL,
|
||||
|
||||
// Banked Registers
|
||||
ARM_SYSREG_R8_USR,
|
||||
ARM_SYSREG_R9_USR,
|
||||
ARM_SYSREG_R10_USR,
|
||||
ARM_SYSREG_R11_USR,
|
||||
ARM_SYSREG_R12_USR,
|
||||
ARM_SYSREG_SP_USR,
|
||||
ARM_SYSREG_LR_USR,
|
||||
ARM_SYSREG_R8_FIQ,
|
||||
ARM_SYSREG_R9_FIQ,
|
||||
ARM_SYSREG_R10_FIQ,
|
||||
ARM_SYSREG_R11_FIQ,
|
||||
ARM_SYSREG_R12_FIQ,
|
||||
ARM_SYSREG_SP_FIQ,
|
||||
ARM_SYSREG_LR_FIQ,
|
||||
ARM_SYSREG_LR_IRQ,
|
||||
ARM_SYSREG_SP_IRQ,
|
||||
ARM_SYSREG_LR_SVC,
|
||||
ARM_SYSREG_SP_SVC,
|
||||
ARM_SYSREG_LR_ABT,
|
||||
ARM_SYSREG_SP_ABT,
|
||||
ARM_SYSREG_LR_UND,
|
||||
ARM_SYSREG_SP_UND,
|
||||
ARM_SYSREG_LR_MON,
|
||||
ARM_SYSREG_SP_MON,
|
||||
ARM_SYSREG_ELR_HYP,
|
||||
ARM_SYSREG_SP_HYP,
|
||||
|
||||
ARM_SYSREG_SPSR_FIQ,
|
||||
ARM_SYSREG_SPSR_IRQ,
|
||||
ARM_SYSREG_SPSR_SVC,
|
||||
ARM_SYSREG_SPSR_ABT,
|
||||
ARM_SYSREG_SPSR_UND,
|
||||
ARM_SYSREG_SPSR_MON,
|
||||
ARM_SYSREG_SPSR_HYP,
|
||||
} arm_sysreg;
|
||||
|
||||
/// The memory barrier constants map directly to the 4-bit encoding of
|
||||
/// the option field for Memory Barrier operations.
|
||||
typedef enum arm_mem_barrier {
|
||||
ARM_MB_INVALID = 0,
|
||||
ARM_MB_RESERVED_0,
|
||||
ARM_MB_OSHLD,
|
||||
ARM_MB_OSHST,
|
||||
ARM_MB_OSH,
|
||||
ARM_MB_RESERVED_4,
|
||||
ARM_MB_NSHLD,
|
||||
ARM_MB_NSHST,
|
||||
ARM_MB_NSH,
|
||||
ARM_MB_RESERVED_8,
|
||||
ARM_MB_ISHLD,
|
||||
ARM_MB_ISHST,
|
||||
ARM_MB_ISH,
|
||||
ARM_MB_RESERVED_12,
|
||||
ARM_MB_LD,
|
||||
ARM_MB_ST,
|
||||
ARM_MB_SY,
|
||||
} arm_mem_barrier;
|
||||
|
||||
/// Operand type for instruction's operands
|
||||
typedef enum arm_op_type {
|
||||
ARM_OP_INVALID = 0, ///< = CS_OP_INVALID (Uninitialized).
|
||||
ARM_OP_REG, ///< = CS_OP_REG (Register operand).
|
||||
ARM_OP_IMM, ///< = CS_OP_IMM (Immediate operand).
|
||||
ARM_OP_MEM, ///< = CS_OP_MEM (Memory operand).
|
||||
ARM_OP_FP, ///< = CS_OP_FP (Floating-Point operand).
|
||||
ARM_OP_CIMM = 64, ///< C-Immediate (coprocessor registers)
|
||||
ARM_OP_PIMM, ///< P-Immediate (coprocessor registers)
|
||||
ARM_OP_SETEND, ///< operand for SETEND instruction
|
||||
ARM_OP_SYSREG, ///< MSR/MRS special register operand
|
||||
} arm_op_type;
|
||||
|
||||
/// Operand type for SETEND instruction
|
||||
typedef enum arm_setend_type {
|
||||
ARM_SETEND_INVALID = 0, ///< Uninitialized.
|
||||
ARM_SETEND_BE, ///< BE operand.
|
||||
ARM_SETEND_LE, ///< LE operand
|
||||
} arm_setend_type;
|
||||
|
||||
typedef enum arm_cpsmode_type {
|
||||
ARM_CPSMODE_INVALID = 0,
|
||||
ARM_CPSMODE_IE = 2,
|
||||
ARM_CPSMODE_ID = 3
|
||||
} arm_cpsmode_type;
|
||||
|
||||
/// Operand type for SETEND instruction
|
||||
typedef enum arm_cpsflag_type {
|
||||
ARM_CPSFLAG_INVALID = 0,
|
||||
ARM_CPSFLAG_F = 1,
|
||||
ARM_CPSFLAG_I = 2,
|
||||
ARM_CPSFLAG_A = 4,
|
||||
ARM_CPSFLAG_NONE = 16, ///< no flag
|
||||
} arm_cpsflag_type;
|
||||
|
||||
/// Data type for elements of vector instructions.
|
||||
typedef enum arm_vectordata_type {
|
||||
ARM_VECTORDATA_INVALID = 0,
|
||||
|
||||
// Integer type
|
||||
ARM_VECTORDATA_I8,
|
||||
ARM_VECTORDATA_I16,
|
||||
ARM_VECTORDATA_I32,
|
||||
ARM_VECTORDATA_I64,
|
||||
|
||||
// Signed integer type
|
||||
ARM_VECTORDATA_S8,
|
||||
ARM_VECTORDATA_S16,
|
||||
ARM_VECTORDATA_S32,
|
||||
ARM_VECTORDATA_S64,
|
||||
|
||||
// Unsigned integer type
|
||||
ARM_VECTORDATA_U8,
|
||||
ARM_VECTORDATA_U16,
|
||||
ARM_VECTORDATA_U32,
|
||||
ARM_VECTORDATA_U64,
|
||||
|
||||
// Data type for VMUL/VMULL
|
||||
ARM_VECTORDATA_P8,
|
||||
|
||||
// Floating type
|
||||
ARM_VECTORDATA_F32,
|
||||
ARM_VECTORDATA_F64,
|
||||
|
||||
// Convert float <-> float
|
||||
ARM_VECTORDATA_F16F64, // f16.f64
|
||||
ARM_VECTORDATA_F64F16, // f64.f16
|
||||
ARM_VECTORDATA_F32F16, // f32.f16
|
||||
ARM_VECTORDATA_F16F32, // f32.f16
|
||||
ARM_VECTORDATA_F64F32, // f64.f32
|
||||
ARM_VECTORDATA_F32F64, // f32.f64
|
||||
|
||||
// Convert integer <-> float
|
||||
ARM_VECTORDATA_S32F32, // s32.f32
|
||||
ARM_VECTORDATA_U32F32, // u32.f32
|
||||
ARM_VECTORDATA_F32S32, // f32.s32
|
||||
ARM_VECTORDATA_F32U32, // f32.u32
|
||||
ARM_VECTORDATA_F64S16, // f64.s16
|
||||
ARM_VECTORDATA_F32S16, // f32.s16
|
||||
ARM_VECTORDATA_F64S32, // f64.s32
|
||||
ARM_VECTORDATA_S16F64, // s16.f64
|
||||
ARM_VECTORDATA_S16F32, // s16.f64
|
||||
ARM_VECTORDATA_S32F64, // s32.f64
|
||||
ARM_VECTORDATA_U16F64, // u16.f64
|
||||
ARM_VECTORDATA_U16F32, // u16.f32
|
||||
ARM_VECTORDATA_U32F64, // u32.f64
|
||||
ARM_VECTORDATA_F64U16, // f64.u16
|
||||
ARM_VECTORDATA_F32U16, // f32.u16
|
||||
ARM_VECTORDATA_F64U32, // f64.u32
|
||||
} arm_vectordata_type;
|
||||
|
||||
/// ARM registers
|
||||
typedef enum arm_reg {
|
||||
ARM_REG_INVALID = 0,
|
||||
ARM_REG_APSR,
|
||||
ARM_REG_APSR_NZCV,
|
||||
ARM_REG_CPSR,
|
||||
ARM_REG_FPEXC,
|
||||
ARM_REG_FPINST,
|
||||
ARM_REG_FPSCR,
|
||||
ARM_REG_FPSCR_NZCV,
|
||||
ARM_REG_FPSID,
|
||||
ARM_REG_ITSTATE,
|
||||
ARM_REG_LR,
|
||||
ARM_REG_PC,
|
||||
ARM_REG_SP,
|
||||
ARM_REG_SPSR,
|
||||
ARM_REG_D0,
|
||||
ARM_REG_D1,
|
||||
ARM_REG_D2,
|
||||
ARM_REG_D3,
|
||||
ARM_REG_D4,
|
||||
ARM_REG_D5,
|
||||
ARM_REG_D6,
|
||||
ARM_REG_D7,
|
||||
ARM_REG_D8,
|
||||
ARM_REG_D9,
|
||||
ARM_REG_D10,
|
||||
ARM_REG_D11,
|
||||
ARM_REG_D12,
|
||||
ARM_REG_D13,
|
||||
ARM_REG_D14,
|
||||
ARM_REG_D15,
|
||||
ARM_REG_D16,
|
||||
ARM_REG_D17,
|
||||
ARM_REG_D18,
|
||||
ARM_REG_D19,
|
||||
ARM_REG_D20,
|
||||
ARM_REG_D21,
|
||||
ARM_REG_D22,
|
||||
ARM_REG_D23,
|
||||
ARM_REG_D24,
|
||||
ARM_REG_D25,
|
||||
ARM_REG_D26,
|
||||
ARM_REG_D27,
|
||||
ARM_REG_D28,
|
||||
ARM_REG_D29,
|
||||
ARM_REG_D30,
|
||||
ARM_REG_D31,
|
||||
ARM_REG_FPINST2,
|
||||
ARM_REG_MVFR0,
|
||||
ARM_REG_MVFR1,
|
||||
ARM_REG_MVFR2,
|
||||
ARM_REG_Q0,
|
||||
ARM_REG_Q1,
|
||||
ARM_REG_Q2,
|
||||
ARM_REG_Q3,
|
||||
ARM_REG_Q4,
|
||||
ARM_REG_Q5,
|
||||
ARM_REG_Q6,
|
||||
ARM_REG_Q7,
|
||||
ARM_REG_Q8,
|
||||
ARM_REG_Q9,
|
||||
ARM_REG_Q10,
|
||||
ARM_REG_Q11,
|
||||
ARM_REG_Q12,
|
||||
ARM_REG_Q13,
|
||||
ARM_REG_Q14,
|
||||
ARM_REG_Q15,
|
||||
ARM_REG_R0,
|
||||
ARM_REG_R1,
|
||||
ARM_REG_R2,
|
||||
ARM_REG_R3,
|
||||
ARM_REG_R4,
|
||||
ARM_REG_R5,
|
||||
ARM_REG_R6,
|
||||
ARM_REG_R7,
|
||||
ARM_REG_R8,
|
||||
ARM_REG_R9,
|
||||
ARM_REG_R10,
|
||||
ARM_REG_R11,
|
||||
ARM_REG_R12,
|
||||
ARM_REG_S0,
|
||||
ARM_REG_S1,
|
||||
ARM_REG_S2,
|
||||
ARM_REG_S3,
|
||||
ARM_REG_S4,
|
||||
ARM_REG_S5,
|
||||
ARM_REG_S6,
|
||||
ARM_REG_S7,
|
||||
ARM_REG_S8,
|
||||
ARM_REG_S9,
|
||||
ARM_REG_S10,
|
||||
ARM_REG_S11,
|
||||
ARM_REG_S12,
|
||||
ARM_REG_S13,
|
||||
ARM_REG_S14,
|
||||
ARM_REG_S15,
|
||||
ARM_REG_S16,
|
||||
ARM_REG_S17,
|
||||
ARM_REG_S18,
|
||||
ARM_REG_S19,
|
||||
ARM_REG_S20,
|
||||
ARM_REG_S21,
|
||||
ARM_REG_S22,
|
||||
ARM_REG_S23,
|
||||
ARM_REG_S24,
|
||||
ARM_REG_S25,
|
||||
ARM_REG_S26,
|
||||
ARM_REG_S27,
|
||||
ARM_REG_S28,
|
||||
ARM_REG_S29,
|
||||
ARM_REG_S30,
|
||||
ARM_REG_S31,
|
||||
|
||||
ARM_REG_ENDING, // <-- mark the end of the list or registers
|
||||
|
||||
// alias registers
|
||||
ARM_REG_R13 = ARM_REG_SP,
|
||||
ARM_REG_R14 = ARM_REG_LR,
|
||||
ARM_REG_R15 = ARM_REG_PC,
|
||||
|
||||
ARM_REG_SB = ARM_REG_R9,
|
||||
ARM_REG_SL = ARM_REG_R10,
|
||||
ARM_REG_FP = ARM_REG_R11,
|
||||
ARM_REG_IP = ARM_REG_R12,
|
||||
} arm_reg;
|
||||
|
||||
/// Instruction's operand referring to memory
|
||||
/// This is associated with ARM_OP_MEM operand type above
|
||||
typedef struct arm_op_mem {
|
||||
arm_reg base; ///< base register
|
||||
arm_reg index; ///< index register
|
||||
int scale; ///< scale for index register (can be 1, or -1)
|
||||
int disp; ///< displacement/offset value
|
||||
/// left-shift on index register, or 0 if irrelevant
|
||||
/// NOTE: this value can also be fetched via operand.shift.value
|
||||
int lshift;
|
||||
} arm_op_mem;
|
||||
|
||||
/// Instruction operand
|
||||
typedef struct cs_arm_op {
|
||||
int vector_index; ///< Vector Index for some vector operands (or -1 if irrelevant)
|
||||
|
||||
struct {
|
||||
arm_shifter type;
|
||||
unsigned int value;
|
||||
} shift;
|
||||
|
||||
arm_op_type type; ///< operand type
|
||||
|
||||
union {
|
||||
int reg; ///< register value for REG/SYSREG operand
|
||||
int32_t imm; ///< immediate value for C-IMM, P-IMM or IMM operand
|
||||
double fp; ///< floating point value for FP operand
|
||||
arm_op_mem mem; ///< base/index/scale/disp value for MEM operand
|
||||
arm_setend_type setend; ///< SETEND instruction's operand type
|
||||
};
|
||||
|
||||
/// in some instructions, an operand can be subtracted or added to
|
||||
/// the base register,
|
||||
/// if TRUE, this operand is subtracted. otherwise, it is added.
|
||||
bool subtracted;
|
||||
|
||||
/// How is this operand accessed? (READ, WRITE or READ|WRITE)
|
||||
/// This field is combined of cs_ac_type.
|
||||
/// NOTE: this field is irrelevant if engine is compiled in DIET mode.
|
||||
uint8_t access;
|
||||
|
||||
/// Neon lane index for NEON instructions (or -1 if irrelevant)
|
||||
int8_t neon_lane;
|
||||
} cs_arm_op;
|
||||
|
||||
/// Instruction structure
|
||||
typedef struct cs_arm {
|
||||
bool usermode; ///< User-mode registers to be loaded (for LDM/STM instructions)
|
||||
int vector_size; ///< Scalar size for vector instructions
|
||||
arm_vectordata_type vector_data; ///< Data type for elements of vector instructions
|
||||
arm_cpsmode_type cps_mode; ///< CPS mode for CPS instruction
|
||||
arm_cpsflag_type cps_flag; ///< CPS mode for CPS instruction
|
||||
arm_cc cc; ///< conditional code for this insn
|
||||
bool update_flags; ///< does this insn update flags?
|
||||
bool writeback; ///< does this insn write-back?
|
||||
arm_mem_barrier mem_barrier; ///< Option for some memory barrier instructions
|
||||
|
||||
/// Number of operands of this instruction,
|
||||
/// or 0 when instruction has no operand.
|
||||
uint8_t op_count;
|
||||
|
||||
cs_arm_op operands[36]; ///< operands for this instruction.
|
||||
} cs_arm;
|
||||
|
||||
/// ARM instruction
|
||||
typedef enum arm_insn {
|
||||
ARM_INS_INVALID = 0,
|
||||
|
||||
ARM_INS_ADC,
|
||||
ARM_INS_ADD,
|
||||
ARM_INS_ADR,
|
||||
ARM_INS_AESD,
|
||||
ARM_INS_AESE,
|
||||
ARM_INS_AESIMC,
|
||||
ARM_INS_AESMC,
|
||||
ARM_INS_AND,
|
||||
ARM_INS_BFC,
|
||||
ARM_INS_BFI,
|
||||
ARM_INS_BIC,
|
||||
ARM_INS_BKPT,
|
||||
ARM_INS_BL,
|
||||
ARM_INS_BLX,
|
||||
ARM_INS_BX,
|
||||
ARM_INS_BXJ,
|
||||
ARM_INS_B,
|
||||
ARM_INS_CDP,
|
||||
ARM_INS_CDP2,
|
||||
ARM_INS_CLREX,
|
||||
ARM_INS_CLZ,
|
||||
ARM_INS_CMN,
|
||||
ARM_INS_CMP,
|
||||
ARM_INS_CPS,
|
||||
ARM_INS_CRC32B,
|
||||
ARM_INS_CRC32CB,
|
||||
ARM_INS_CRC32CH,
|
||||
ARM_INS_CRC32CW,
|
||||
ARM_INS_CRC32H,
|
||||
ARM_INS_CRC32W,
|
||||
ARM_INS_DBG,
|
||||
ARM_INS_DMB,
|
||||
ARM_INS_DSB,
|
||||
ARM_INS_EOR,
|
||||
ARM_INS_ERET,
|
||||
ARM_INS_VMOV,
|
||||
ARM_INS_FLDMDBX,
|
||||
ARM_INS_FLDMIAX,
|
||||
ARM_INS_VMRS,
|
||||
ARM_INS_FSTMDBX,
|
||||
ARM_INS_FSTMIAX,
|
||||
ARM_INS_HINT,
|
||||
ARM_INS_HLT,
|
||||
ARM_INS_HVC,
|
||||
ARM_INS_ISB,
|
||||
ARM_INS_LDA,
|
||||
ARM_INS_LDAB,
|
||||
ARM_INS_LDAEX,
|
||||
ARM_INS_LDAEXB,
|
||||
ARM_INS_LDAEXD,
|
||||
ARM_INS_LDAEXH,
|
||||
ARM_INS_LDAH,
|
||||
ARM_INS_LDC2L,
|
||||
ARM_INS_LDC2,
|
||||
ARM_INS_LDCL,
|
||||
ARM_INS_LDC,
|
||||
ARM_INS_LDMDA,
|
||||
ARM_INS_LDMDB,
|
||||
ARM_INS_LDM,
|
||||
ARM_INS_LDMIB,
|
||||
ARM_INS_LDRBT,
|
||||
ARM_INS_LDRB,
|
||||
ARM_INS_LDRD,
|
||||
ARM_INS_LDREX,
|
||||
ARM_INS_LDREXB,
|
||||
ARM_INS_LDREXD,
|
||||
ARM_INS_LDREXH,
|
||||
ARM_INS_LDRH,
|
||||
ARM_INS_LDRHT,
|
||||
ARM_INS_LDRSB,
|
||||
ARM_INS_LDRSBT,
|
||||
ARM_INS_LDRSH,
|
||||
ARM_INS_LDRSHT,
|
||||
ARM_INS_LDRT,
|
||||
ARM_INS_LDR,
|
||||
ARM_INS_MCR,
|
||||
ARM_INS_MCR2,
|
||||
ARM_INS_MCRR,
|
||||
ARM_INS_MCRR2,
|
||||
ARM_INS_MLA,
|
||||
ARM_INS_MLS,
|
||||
ARM_INS_MOV,
|
||||
ARM_INS_MOVT,
|
||||
ARM_INS_MOVW,
|
||||
ARM_INS_MRC,
|
||||
ARM_INS_MRC2,
|
||||
ARM_INS_MRRC,
|
||||
ARM_INS_MRRC2,
|
||||
ARM_INS_MRS,
|
||||
ARM_INS_MSR,
|
||||
ARM_INS_MUL,
|
||||
ARM_INS_MVN,
|
||||
ARM_INS_ORR,
|
||||
ARM_INS_PKHBT,
|
||||
ARM_INS_PKHTB,
|
||||
ARM_INS_PLDW,
|
||||
ARM_INS_PLD,
|
||||
ARM_INS_PLI,
|
||||
ARM_INS_QADD,
|
||||
ARM_INS_QADD16,
|
||||
ARM_INS_QADD8,
|
||||
ARM_INS_QASX,
|
||||
ARM_INS_QDADD,
|
||||
ARM_INS_QDSUB,
|
||||
ARM_INS_QSAX,
|
||||
ARM_INS_QSUB,
|
||||
ARM_INS_QSUB16,
|
||||
ARM_INS_QSUB8,
|
||||
ARM_INS_RBIT,
|
||||
ARM_INS_REV,
|
||||
ARM_INS_REV16,
|
||||
ARM_INS_REVSH,
|
||||
ARM_INS_RFEDA,
|
||||
ARM_INS_RFEDB,
|
||||
ARM_INS_RFEIA,
|
||||
ARM_INS_RFEIB,
|
||||
ARM_INS_RSB,
|
||||
ARM_INS_RSC,
|
||||
ARM_INS_SADD16,
|
||||
ARM_INS_SADD8,
|
||||
ARM_INS_SASX,
|
||||
ARM_INS_SBC,
|
||||
ARM_INS_SBFX,
|
||||
ARM_INS_SDIV,
|
||||
ARM_INS_SEL,
|
||||
ARM_INS_SETEND,
|
||||
ARM_INS_SHA1C,
|
||||
ARM_INS_SHA1H,
|
||||
ARM_INS_SHA1M,
|
||||
ARM_INS_SHA1P,
|
||||
ARM_INS_SHA1SU0,
|
||||
ARM_INS_SHA1SU1,
|
||||
ARM_INS_SHA256H,
|
||||
ARM_INS_SHA256H2,
|
||||
ARM_INS_SHA256SU0,
|
||||
ARM_INS_SHA256SU1,
|
||||
ARM_INS_SHADD16,
|
||||
ARM_INS_SHADD8,
|
||||
ARM_INS_SHASX,
|
||||
ARM_INS_SHSAX,
|
||||
ARM_INS_SHSUB16,
|
||||
ARM_INS_SHSUB8,
|
||||
ARM_INS_SMC,
|
||||
ARM_INS_SMLABB,
|
||||
ARM_INS_SMLABT,
|
||||
ARM_INS_SMLAD,
|
||||
ARM_INS_SMLADX,
|
||||
ARM_INS_SMLAL,
|
||||
ARM_INS_SMLALBB,
|
||||
ARM_INS_SMLALBT,
|
||||
ARM_INS_SMLALD,
|
||||
ARM_INS_SMLALDX,
|
||||
ARM_INS_SMLALTB,
|
||||
ARM_INS_SMLALTT,
|
||||
ARM_INS_SMLATB,
|
||||
ARM_INS_SMLATT,
|
||||
ARM_INS_SMLAWB,
|
||||
ARM_INS_SMLAWT,
|
||||
ARM_INS_SMLSD,
|
||||
ARM_INS_SMLSDX,
|
||||
ARM_INS_SMLSLD,
|
||||
ARM_INS_SMLSLDX,
|
||||
ARM_INS_SMMLA,
|
||||
ARM_INS_SMMLAR,
|
||||
ARM_INS_SMMLS,
|
||||
ARM_INS_SMMLSR,
|
||||
ARM_INS_SMMUL,
|
||||
ARM_INS_SMMULR,
|
||||
ARM_INS_SMUAD,
|
||||
ARM_INS_SMUADX,
|
||||
ARM_INS_SMULBB,
|
||||
ARM_INS_SMULBT,
|
||||
ARM_INS_SMULL,
|
||||
ARM_INS_SMULTB,
|
||||
ARM_INS_SMULTT,
|
||||
ARM_INS_SMULWB,
|
||||
ARM_INS_SMULWT,
|
||||
ARM_INS_SMUSD,
|
||||
ARM_INS_SMUSDX,
|
||||
ARM_INS_SRSDA,
|
||||
ARM_INS_SRSDB,
|
||||
ARM_INS_SRSIA,
|
||||
ARM_INS_SRSIB,
|
||||
ARM_INS_SSAT,
|
||||
ARM_INS_SSAT16,
|
||||
ARM_INS_SSAX,
|
||||
ARM_INS_SSUB16,
|
||||
ARM_INS_SSUB8,
|
||||
ARM_INS_STC2L,
|
||||
ARM_INS_STC2,
|
||||
ARM_INS_STCL,
|
||||
ARM_INS_STC,
|
||||
ARM_INS_STL,
|
||||
ARM_INS_STLB,
|
||||
ARM_INS_STLEX,
|
||||
ARM_INS_STLEXB,
|
||||
ARM_INS_STLEXD,
|
||||
ARM_INS_STLEXH,
|
||||
ARM_INS_STLH,
|
||||
ARM_INS_STMDA,
|
||||
ARM_INS_STMDB,
|
||||
ARM_INS_STM,
|
||||
ARM_INS_STMIB,
|
||||
ARM_INS_STRBT,
|
||||
ARM_INS_STRB,
|
||||
ARM_INS_STRD,
|
||||
ARM_INS_STREX,
|
||||
ARM_INS_STREXB,
|
||||
ARM_INS_STREXD,
|
||||
ARM_INS_STREXH,
|
||||
ARM_INS_STRH,
|
||||
ARM_INS_STRHT,
|
||||
ARM_INS_STRT,
|
||||
ARM_INS_STR,
|
||||
ARM_INS_SUB,
|
||||
ARM_INS_SVC,
|
||||
ARM_INS_SWP,
|
||||
ARM_INS_SWPB,
|
||||
ARM_INS_SXTAB,
|
||||
ARM_INS_SXTAB16,
|
||||
ARM_INS_SXTAH,
|
||||
ARM_INS_SXTB,
|
||||
ARM_INS_SXTB16,
|
||||
ARM_INS_SXTH,
|
||||
ARM_INS_TEQ,
|
||||
ARM_INS_TRAP,
|
||||
ARM_INS_TST,
|
||||
ARM_INS_UADD16,
|
||||
ARM_INS_UADD8,
|
||||
ARM_INS_UASX,
|
||||
ARM_INS_UBFX,
|
||||
ARM_INS_UDF,
|
||||
ARM_INS_UDIV,
|
||||
ARM_INS_UHADD16,
|
||||
ARM_INS_UHADD8,
|
||||
ARM_INS_UHASX,
|
||||
ARM_INS_UHSAX,
|
||||
ARM_INS_UHSUB16,
|
||||
ARM_INS_UHSUB8,
|
||||
ARM_INS_UMAAL,
|
||||
ARM_INS_UMLAL,
|
||||
ARM_INS_UMULL,
|
||||
ARM_INS_UQADD16,
|
||||
ARM_INS_UQADD8,
|
||||
ARM_INS_UQASX,
|
||||
ARM_INS_UQSAX,
|
||||
ARM_INS_UQSUB16,
|
||||
ARM_INS_UQSUB8,
|
||||
ARM_INS_USAD8,
|
||||
ARM_INS_USADA8,
|
||||
ARM_INS_USAT,
|
||||
ARM_INS_USAT16,
|
||||
ARM_INS_USAX,
|
||||
ARM_INS_USUB16,
|
||||
ARM_INS_USUB8,
|
||||
ARM_INS_UXTAB,
|
||||
ARM_INS_UXTAB16,
|
||||
ARM_INS_UXTAH,
|
||||
ARM_INS_UXTB,
|
||||
ARM_INS_UXTB16,
|
||||
ARM_INS_UXTH,
|
||||
ARM_INS_VABAL,
|
||||
ARM_INS_VABA,
|
||||
ARM_INS_VABDL,
|
||||
ARM_INS_VABD,
|
||||
ARM_INS_VABS,
|
||||
ARM_INS_VACGE,
|
||||
ARM_INS_VACGT,
|
||||
ARM_INS_VADD,
|
||||
ARM_INS_VADDHN,
|
||||
ARM_INS_VADDL,
|
||||
ARM_INS_VADDW,
|
||||
ARM_INS_VAND,
|
||||
ARM_INS_VBIC,
|
||||
ARM_INS_VBIF,
|
||||
ARM_INS_VBIT,
|
||||
ARM_INS_VBSL,
|
||||
ARM_INS_VCEQ,
|
||||
ARM_INS_VCGE,
|
||||
ARM_INS_VCGT,
|
||||
ARM_INS_VCLE,
|
||||
ARM_INS_VCLS,
|
||||
ARM_INS_VCLT,
|
||||
ARM_INS_VCLZ,
|
||||
ARM_INS_VCMP,
|
||||
ARM_INS_VCMPE,
|
||||
ARM_INS_VCNT,
|
||||
ARM_INS_VCVTA,
|
||||
ARM_INS_VCVTB,
|
||||
ARM_INS_VCVT,
|
||||
ARM_INS_VCVTM,
|
||||
ARM_INS_VCVTN,
|
||||
ARM_INS_VCVTP,
|
||||
ARM_INS_VCVTT,
|
||||
ARM_INS_VDIV,
|
||||
ARM_INS_VDUP,
|
||||
ARM_INS_VEOR,
|
||||
ARM_INS_VEXT,
|
||||
ARM_INS_VFMA,
|
||||
ARM_INS_VFMS,
|
||||
ARM_INS_VFNMA,
|
||||
ARM_INS_VFNMS,
|
||||
ARM_INS_VHADD,
|
||||
ARM_INS_VHSUB,
|
||||
ARM_INS_VLD1,
|
||||
ARM_INS_VLD2,
|
||||
ARM_INS_VLD3,
|
||||
ARM_INS_VLD4,
|
||||
ARM_INS_VLDMDB,
|
||||
ARM_INS_VLDMIA,
|
||||
ARM_INS_VLDR,
|
||||
ARM_INS_VMAXNM,
|
||||
ARM_INS_VMAX,
|
||||
ARM_INS_VMINNM,
|
||||
ARM_INS_VMIN,
|
||||
ARM_INS_VMLA,
|
||||
ARM_INS_VMLAL,
|
||||
ARM_INS_VMLS,
|
||||
ARM_INS_VMLSL,
|
||||
ARM_INS_VMOVL,
|
||||
ARM_INS_VMOVN,
|
||||
ARM_INS_VMSR,
|
||||
ARM_INS_VMUL,
|
||||
ARM_INS_VMULL,
|
||||
ARM_INS_VMVN,
|
||||
ARM_INS_VNEG,
|
||||
ARM_INS_VNMLA,
|
||||
ARM_INS_VNMLS,
|
||||
ARM_INS_VNMUL,
|
||||
ARM_INS_VORN,
|
||||
ARM_INS_VORR,
|
||||
ARM_INS_VPADAL,
|
||||
ARM_INS_VPADDL,
|
||||
ARM_INS_VPADD,
|
||||
ARM_INS_VPMAX,
|
||||
ARM_INS_VPMIN,
|
||||
ARM_INS_VQABS,
|
||||
ARM_INS_VQADD,
|
||||
ARM_INS_VQDMLAL,
|
||||
ARM_INS_VQDMLSL,
|
||||
ARM_INS_VQDMULH,
|
||||
ARM_INS_VQDMULL,
|
||||
ARM_INS_VQMOVUN,
|
||||
ARM_INS_VQMOVN,
|
||||
ARM_INS_VQNEG,
|
||||
ARM_INS_VQRDMULH,
|
||||
ARM_INS_VQRSHL,
|
||||
ARM_INS_VQRSHRN,
|
||||
ARM_INS_VQRSHRUN,
|
||||
ARM_INS_VQSHL,
|
||||
ARM_INS_VQSHLU,
|
||||
ARM_INS_VQSHRN,
|
||||
ARM_INS_VQSHRUN,
|
||||
ARM_INS_VQSUB,
|
||||
ARM_INS_VRADDHN,
|
||||
ARM_INS_VRECPE,
|
||||
ARM_INS_VRECPS,
|
||||
ARM_INS_VREV16,
|
||||
ARM_INS_VREV32,
|
||||
ARM_INS_VREV64,
|
||||
ARM_INS_VRHADD,
|
||||
ARM_INS_VRINTA,
|
||||
ARM_INS_VRINTM,
|
||||
ARM_INS_VRINTN,
|
||||
ARM_INS_VRINTP,
|
||||
ARM_INS_VRINTR,
|
||||
ARM_INS_VRINTX,
|
||||
ARM_INS_VRINTZ,
|
||||
ARM_INS_VRSHL,
|
||||
ARM_INS_VRSHRN,
|
||||
ARM_INS_VRSHR,
|
||||
ARM_INS_VRSQRTE,
|
||||
ARM_INS_VRSQRTS,
|
||||
ARM_INS_VRSRA,
|
||||
ARM_INS_VRSUBHN,
|
||||
ARM_INS_VSELEQ,
|
||||
ARM_INS_VSELGE,
|
||||
ARM_INS_VSELGT,
|
||||
ARM_INS_VSELVS,
|
||||
ARM_INS_VSHLL,
|
||||
ARM_INS_VSHL,
|
||||
ARM_INS_VSHRN,
|
||||
ARM_INS_VSHR,
|
||||
ARM_INS_VSLI,
|
||||
ARM_INS_VSQRT,
|
||||
ARM_INS_VSRA,
|
||||
ARM_INS_VSRI,
|
||||
ARM_INS_VST1,
|
||||
ARM_INS_VST2,
|
||||
ARM_INS_VST3,
|
||||
ARM_INS_VST4,
|
||||
ARM_INS_VSTMDB,
|
||||
ARM_INS_VSTMIA,
|
||||
ARM_INS_VSTR,
|
||||
ARM_INS_VSUB,
|
||||
ARM_INS_VSUBHN,
|
||||
ARM_INS_VSUBL,
|
||||
ARM_INS_VSUBW,
|
||||
ARM_INS_VSWP,
|
||||
ARM_INS_VTBL,
|
||||
ARM_INS_VTBX,
|
||||
ARM_INS_VCVTR,
|
||||
ARM_INS_VTRN,
|
||||
ARM_INS_VTST,
|
||||
ARM_INS_VUZP,
|
||||
ARM_INS_VZIP,
|
||||
ARM_INS_ADDW,
|
||||
ARM_INS_ASR,
|
||||
ARM_INS_DCPS1,
|
||||
ARM_INS_DCPS2,
|
||||
ARM_INS_DCPS3,
|
||||
ARM_INS_IT,
|
||||
ARM_INS_LSL,
|
||||
ARM_INS_LSR,
|
||||
ARM_INS_ORN,
|
||||
ARM_INS_ROR,
|
||||
ARM_INS_RRX,
|
||||
ARM_INS_SUBW,
|
||||
ARM_INS_TBB,
|
||||
ARM_INS_TBH,
|
||||
ARM_INS_CBNZ,
|
||||
ARM_INS_CBZ,
|
||||
ARM_INS_POP,
|
||||
ARM_INS_PUSH,
|
||||
|
||||
// special instructions
|
||||
ARM_INS_NOP,
|
||||
ARM_INS_YIELD,
|
||||
ARM_INS_WFE,
|
||||
ARM_INS_WFI,
|
||||
ARM_INS_SEV,
|
||||
ARM_INS_SEVL,
|
||||
ARM_INS_VPUSH,
|
||||
ARM_INS_VPOP,
|
||||
|
||||
ARM_INS_ENDING, // <-- mark the end of the list of instructions
|
||||
} arm_insn;
|
||||
|
||||
/// Group of ARM instructions
|
||||
typedef enum arm_insn_group {
|
||||
ARM_GRP_INVALID = 0, ///< = CS_GRP_INVALID
|
||||
|
||||
// Generic groups
|
||||
// all jump instructions (conditional+direct+indirect jumps)
|
||||
ARM_GRP_JUMP, ///< = CS_GRP_JUMP
|
||||
ARM_GRP_CALL, ///< = CS_GRP_CALL
|
||||
ARM_GRP_INT = 4, ///< = CS_GRP_INT
|
||||
ARM_GRP_PRIVILEGE = 6, ///< = CS_GRP_PRIVILEGE
|
||||
ARM_GRP_BRANCH_RELATIVE, ///< = CS_GRP_BRANCH_RELATIVE
|
||||
|
||||
// Architecture-specific groups
|
||||
ARM_GRP_CRYPTO = 128,
|
||||
ARM_GRP_DATABARRIER,
|
||||
ARM_GRP_DIVIDE,
|
||||
ARM_GRP_FPARMV8,
|
||||
ARM_GRP_MULTPRO,
|
||||
ARM_GRP_NEON,
|
||||
ARM_GRP_T2EXTRACTPACK,
|
||||
ARM_GRP_THUMB2DSP,
|
||||
ARM_GRP_TRUSTZONE,
|
||||
ARM_GRP_V4T,
|
||||
ARM_GRP_V5T,
|
||||
ARM_GRP_V5TE,
|
||||
ARM_GRP_V6,
|
||||
ARM_GRP_V6T2,
|
||||
ARM_GRP_V7,
|
||||
ARM_GRP_V8,
|
||||
ARM_GRP_VFP2,
|
||||
ARM_GRP_VFP3,
|
||||
ARM_GRP_VFP4,
|
||||
ARM_GRP_ARM,
|
||||
ARM_GRP_MCLASS,
|
||||
ARM_GRP_NOTMCLASS,
|
||||
ARM_GRP_THUMB,
|
||||
ARM_GRP_THUMB1ONLY,
|
||||
ARM_GRP_THUMB2,
|
||||
ARM_GRP_PREV8,
|
||||
ARM_GRP_FPVMLX,
|
||||
ARM_GRP_MULOPS,
|
||||
ARM_GRP_CRC,
|
||||
ARM_GRP_DPVFP,
|
||||
ARM_GRP_V6M,
|
||||
ARM_GRP_VIRTUALIZATION,
|
||||
|
||||
ARM_GRP_ENDING,
|
||||
} arm_insn_group;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,766 @@
|
||||
#ifndef CAPSTONE_ENGINE_H
|
||||
#define CAPSTONE_ENGINE_H
|
||||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2016 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#if defined(CAPSTONE_HAS_OSXKERNEL)
|
||||
#include <libkern/libkern.h>
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#pragma warning(disable:4100)
|
||||
#define CAPSTONE_API __cdecl
|
||||
#ifdef CAPSTONE_SHARED
|
||||
#define CAPSTONE_EXPORT __declspec(dllexport)
|
||||
#else // defined(CAPSTONE_STATIC)
|
||||
#define CAPSTONE_EXPORT
|
||||
#endif
|
||||
#else
|
||||
#define CAPSTONE_API
|
||||
#if defined(__GNUC__) && !defined(CAPSTONE_STATIC)
|
||||
#define CAPSTONE_EXPORT __attribute__((visibility("default")))
|
||||
#else // defined(CAPSTONE_STATIC)
|
||||
#define CAPSTONE_EXPORT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define CAPSTONE_DEPRECATED __attribute__((deprecated))
|
||||
#elif defined(_MSC_VER)
|
||||
#define CAPSTONE_DEPRECATED __declspec(deprecated)
|
||||
#else
|
||||
#pragma message("WARNING: You need to implement CAPSTONE_DEPRECATED for this compiler")
|
||||
#define CAPSTONE_DEPRECATED
|
||||
#endif
|
||||
|
||||
// Capstone API version
|
||||
#define CS_API_MAJOR 4
|
||||
#define CS_API_MINOR 0
|
||||
|
||||
// Version for bleeding edge code of the Github's "next" branch.
|
||||
// Use this if you want the absolutely latest development code.
|
||||
// This version number will be bumped up whenever we have a new major change.
|
||||
#define CS_NEXT_VERSION 5
|
||||
|
||||
// Capstone package version
|
||||
#define CS_VERSION_MAJOR CS_API_MAJOR
|
||||
#define CS_VERSION_MINOR CS_API_MINOR
|
||||
#define CS_VERSION_EXTRA 1
|
||||
|
||||
/// Macro to create combined version which can be compared to
|
||||
/// result of cs_version() API.
|
||||
#define CS_MAKE_VERSION(major, minor) ((major << 8) + minor)
|
||||
|
||||
/// Maximum size of an instruction mnemonic string.
|
||||
#define CS_MNEMONIC_SIZE 32
|
||||
|
||||
// Handle using with all API
|
||||
typedef size_t csh;
|
||||
|
||||
/// Architecture type
|
||||
typedef enum cs_arch {
|
||||
CS_ARCH_ARM = 0, ///< ARM architecture (including Thumb, Thumb-2)
|
||||
CS_ARCH_ARM64, ///< ARM-64, also called AArch64
|
||||
CS_ARCH_MIPS, ///< Mips architecture
|
||||
CS_ARCH_X86, ///< X86 architecture (including x86 & x86-64)
|
||||
CS_ARCH_PPC, ///< PowerPC architecture
|
||||
CS_ARCH_SPARC, ///< Sparc architecture
|
||||
CS_ARCH_SYSZ, ///< SystemZ architecture
|
||||
CS_ARCH_XCORE, ///< XCore architecture
|
||||
CS_ARCH_M68K, ///< 68K architecture
|
||||
CS_ARCH_TMS320C64X, ///< TMS320C64x architecture
|
||||
CS_ARCH_M680X, ///< 680X architecture
|
||||
CS_ARCH_EVM, ///< Ethereum architecture
|
||||
CS_ARCH_MAX,
|
||||
CS_ARCH_ALL = 0xFFFF, // All architectures - for cs_support()
|
||||
} cs_arch;
|
||||
|
||||
// Support value to verify diet mode of the engine.
|
||||
// If cs_support(CS_SUPPORT_DIET) return True, the engine was compiled
|
||||
// in diet mode.
|
||||
#define CS_SUPPORT_DIET (CS_ARCH_ALL + 1)
|
||||
|
||||
// Support value to verify X86 reduce mode of the engine.
|
||||
// If cs_support(CS_SUPPORT_X86_REDUCE) return True, the engine was compiled
|
||||
// in X86 reduce mode.
|
||||
#define CS_SUPPORT_X86_REDUCE (CS_ARCH_ALL + 2)
|
||||
|
||||
/// Mode type
|
||||
typedef enum cs_mode {
|
||||
CS_MODE_LITTLE_ENDIAN = 0, ///< little-endian mode (default mode)
|
||||
CS_MODE_ARM = 0, ///< 32-bit ARM
|
||||
CS_MODE_16 = 1 << 1, ///< 16-bit mode (X86)
|
||||
CS_MODE_32 = 1 << 2, ///< 32-bit mode (X86)
|
||||
CS_MODE_64 = 1 << 3, ///< 64-bit mode (X86, PPC)
|
||||
CS_MODE_THUMB = 1 << 4, ///< ARM's Thumb mode, including Thumb-2
|
||||
CS_MODE_MCLASS = 1 << 5, ///< ARM's Cortex-M series
|
||||
CS_MODE_V8 = 1 << 6, ///< ARMv8 A32 encodings for ARM
|
||||
CS_MODE_MICRO = 1 << 4, ///< MicroMips mode (MIPS)
|
||||
CS_MODE_MIPS3 = 1 << 5, ///< Mips III ISA
|
||||
CS_MODE_MIPS32R6 = 1 << 6, ///< Mips32r6 ISA
|
||||
CS_MODE_MIPS2 = 1 << 7, ///< Mips II ISA
|
||||
CS_MODE_V9 = 1 << 4, ///< SparcV9 mode (Sparc)
|
||||
CS_MODE_QPX = 1 << 4, ///< Quad Processing eXtensions mode (PPC)
|
||||
CS_MODE_M68K_000 = 1 << 1, ///< M68K 68000 mode
|
||||
CS_MODE_M68K_010 = 1 << 2, ///< M68K 68010 mode
|
||||
CS_MODE_M68K_020 = 1 << 3, ///< M68K 68020 mode
|
||||
CS_MODE_M68K_030 = 1 << 4, ///< M68K 68030 mode
|
||||
CS_MODE_M68K_040 = 1 << 5, ///< M68K 68040 mode
|
||||
CS_MODE_M68K_060 = 1 << 6, ///< M68K 68060 mode
|
||||
CS_MODE_BIG_ENDIAN = 1 << 31, ///< big-endian mode
|
||||
CS_MODE_MIPS32 = CS_MODE_32, ///< Mips32 ISA (Mips)
|
||||
CS_MODE_MIPS64 = CS_MODE_64, ///< Mips64 ISA (Mips)
|
||||
CS_MODE_M680X_6301 = 1 << 1, ///< M680X Hitachi 6301,6303 mode
|
||||
CS_MODE_M680X_6309 = 1 << 2, ///< M680X Hitachi 6309 mode
|
||||
CS_MODE_M680X_6800 = 1 << 3, ///< M680X Motorola 6800,6802 mode
|
||||
CS_MODE_M680X_6801 = 1 << 4, ///< M680X Motorola 6801,6803 mode
|
||||
CS_MODE_M680X_6805 = 1 << 5, ///< M680X Motorola/Freescale 6805 mode
|
||||
CS_MODE_M680X_6808 = 1 << 6, ///< M680X Motorola/Freescale/NXP 68HC08 mode
|
||||
CS_MODE_M680X_6809 = 1 << 7, ///< M680X Motorola 6809 mode
|
||||
CS_MODE_M680X_6811 = 1 << 8, ///< M680X Motorola/Freescale/NXP 68HC11 mode
|
||||
CS_MODE_M680X_CPU12 = 1 << 9, ///< M680X Motorola/Freescale/NXP CPU12
|
||||
///< used on M68HC12/HCS12
|
||||
CS_MODE_M680X_HCS08 = 1 << 10, ///< M680X Freescale/NXP HCS08 mode
|
||||
} cs_mode;
|
||||
|
||||
typedef void* (CAPSTONE_API *cs_malloc_t)(size_t size);
|
||||
typedef void* (CAPSTONE_API *cs_calloc_t)(size_t nmemb, size_t size);
|
||||
typedef void* (CAPSTONE_API *cs_realloc_t)(void *ptr, size_t size);
|
||||
typedef void (CAPSTONE_API *cs_free_t)(void *ptr);
|
||||
typedef int (CAPSTONE_API *cs_vsnprintf_t)(char *str, size_t size, const char *format, va_list ap);
|
||||
|
||||
|
||||
/// User-defined dynamic memory related functions: malloc/calloc/realloc/free/vsnprintf()
|
||||
/// By default, Capstone uses system's malloc(), calloc(), realloc(), free() & vsnprintf().
|
||||
typedef struct cs_opt_mem {
|
||||
cs_malloc_t malloc;
|
||||
cs_calloc_t calloc;
|
||||
cs_realloc_t realloc;
|
||||
cs_free_t free;
|
||||
cs_vsnprintf_t vsnprintf;
|
||||
} cs_opt_mem;
|
||||
|
||||
/// Customize mnemonic for instructions with alternative name.
|
||||
/// To reset existing customized instruction to its default mnemonic,
|
||||
/// call cs_option(CS_OPT_MNEMONIC) again with the same @id and NULL value
|
||||
/// for @mnemonic.
|
||||
typedef struct cs_opt_mnem {
|
||||
/// ID of instruction to be customized.
|
||||
unsigned int id;
|
||||
/// Customized instruction mnemonic.
|
||||
const char *mnemonic;
|
||||
} cs_opt_mnem;
|
||||
|
||||
/// Runtime option for the disassembled engine
|
||||
typedef enum cs_opt_type {
|
||||
CS_OPT_INVALID = 0, ///< No option specified
|
||||
CS_OPT_SYNTAX, ///< Assembly output syntax
|
||||
CS_OPT_DETAIL, ///< Break down instruction structure into details
|
||||
CS_OPT_MODE, ///< Change engine's mode at run-time
|
||||
CS_OPT_MEM, ///< User-defined dynamic memory related functions
|
||||
CS_OPT_SKIPDATA, ///< Skip data when disassembling. Then engine is in SKIPDATA mode.
|
||||
CS_OPT_SKIPDATA_SETUP, ///< Setup user-defined function for SKIPDATA option
|
||||
CS_OPT_MNEMONIC, ///< Customize instruction mnemonic
|
||||
CS_OPT_UNSIGNED, ///< print immediate operands in unsigned form
|
||||
} cs_opt_type;
|
||||
|
||||
/// Runtime option value (associated with option type above)
|
||||
typedef enum cs_opt_value {
|
||||
CS_OPT_OFF = 0, ///< Turn OFF an option - default for CS_OPT_DETAIL, CS_OPT_SKIPDATA, CS_OPT_UNSIGNED.
|
||||
CS_OPT_ON = 3, ///< Turn ON an option (CS_OPT_DETAIL, CS_OPT_SKIPDATA).
|
||||
CS_OPT_SYNTAX_DEFAULT = 0, ///< Default asm syntax (CS_OPT_SYNTAX).
|
||||
CS_OPT_SYNTAX_INTEL, ///< X86 Intel asm syntax - default on X86 (CS_OPT_SYNTAX).
|
||||
CS_OPT_SYNTAX_ATT, ///< X86 ATT asm syntax (CS_OPT_SYNTAX).
|
||||
CS_OPT_SYNTAX_NOREGNAME, ///< Prints register name with only number (CS_OPT_SYNTAX)
|
||||
CS_OPT_SYNTAX_MASM, ///< X86 Intel Masm syntax (CS_OPT_SYNTAX).
|
||||
} cs_opt_value;
|
||||
|
||||
/// Common instruction operand types - to be consistent across all architectures.
|
||||
typedef enum cs_op_type {
|
||||
CS_OP_INVALID = 0, ///< uninitialized/invalid operand.
|
||||
CS_OP_REG, ///< Register operand.
|
||||
CS_OP_IMM, ///< Immediate operand.
|
||||
CS_OP_MEM, ///< Memory operand.
|
||||
CS_OP_FP, ///< Floating-Point operand.
|
||||
} cs_op_type;
|
||||
|
||||
/// 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
|
||||
typedef enum cs_ac_type {
|
||||
CS_AC_INVALID = 0, ///< Uninitialized/invalid access type.
|
||||
CS_AC_READ = 1 << 0, ///< Operand read from memory or register.
|
||||
CS_AC_WRITE = 1 << 1, ///< Operand write to memory or register.
|
||||
} cs_ac_type;
|
||||
|
||||
/// Common instruction groups - to be consistent across all architectures.
|
||||
typedef enum cs_group_type {
|
||||
CS_GRP_INVALID = 0, ///< uninitialized/invalid group.
|
||||
CS_GRP_JUMP, ///< all jump instructions (conditional+direct+indirect jumps)
|
||||
CS_GRP_CALL, ///< all call instructions
|
||||
CS_GRP_RET, ///< all return instructions
|
||||
CS_GRP_INT, ///< all interrupt instructions (int+syscall)
|
||||
CS_GRP_IRET, ///< all interrupt return instructions
|
||||
CS_GRP_PRIVILEGE, ///< all privileged instructions
|
||||
CS_GRP_BRANCH_RELATIVE, ///< all relative branching instructions
|
||||
} cs_group_type;
|
||||
|
||||
/**
|
||||
User-defined callback function for SKIPDATA option.
|
||||
See tests/test_skipdata.c for sample code demonstrating this API.
|
||||
|
||||
@code: the input buffer containing code to be disassembled.
|
||||
This is the same buffer passed to cs_disasm().
|
||||
@code_size: size (in bytes) of the above @code buffer.
|
||||
@offset: the position of the currently-examining byte in the input
|
||||
buffer @code mentioned above.
|
||||
@user_data: user-data passed to cs_option() via @user_data field in
|
||||
cs_opt_skipdata struct below.
|
||||
|
||||
@return: return number of bytes to skip, or 0 to immediately stop disassembling.
|
||||
*/
|
||||
typedef size_t (CAPSTONE_API *cs_skipdata_cb_t)(const uint8_t *code, size_t code_size, size_t offset, void *user_data);
|
||||
|
||||
/// User-customized setup for SKIPDATA option
|
||||
typedef struct cs_opt_skipdata {
|
||||
/// Capstone considers data to skip as special "instructions".
|
||||
/// User can specify the string for this instruction's "mnemonic" here.
|
||||
/// By default (if @mnemonic is NULL), Capstone use ".byte".
|
||||
const char *mnemonic;
|
||||
|
||||
/// User-defined callback function to be called when Capstone hits data.
|
||||
/// If the returned value from this callback is positive (>0), Capstone
|
||||
/// will skip exactly that number of bytes & continue. Otherwise, if
|
||||
/// the callback returns 0, Capstone stops disassembling and returns
|
||||
/// immediately from cs_disasm()
|
||||
/// NOTE: if this callback pointer is NULL, Capstone would skip a number
|
||||
/// of bytes depending on architectures, as following:
|
||||
/// Arm: 2 bytes (Thumb mode) or 4 bytes.
|
||||
/// Arm64: 4 bytes.
|
||||
/// Mips: 4 bytes.
|
||||
/// M680x: 1 byte.
|
||||
/// PowerPC: 4 bytes.
|
||||
/// Sparc: 4 bytes.
|
||||
/// SystemZ: 2 bytes.
|
||||
/// X86: 1 bytes.
|
||||
/// XCore: 2 bytes.
|
||||
/// EVM: 1 bytes.
|
||||
cs_skipdata_cb_t callback; // default value is NULL
|
||||
|
||||
/// User-defined data to be passed to @callback function pointer.
|
||||
void *user_data;
|
||||
} cs_opt_skipdata;
|
||||
|
||||
|
||||
#include "arm.h"
|
||||
#include "arm64.h"
|
||||
#include "m68k.h"
|
||||
#include "mips.h"
|
||||
#include "ppc.h"
|
||||
#include "sparc.h"
|
||||
#include "systemz.h"
|
||||
#include "x86.h"
|
||||
#include "xcore.h"
|
||||
#include "tms320c64x.h"
|
||||
#include "m680x.h"
|
||||
#include "evm.h"
|
||||
|
||||
/// NOTE: All information in cs_detail is only available when CS_OPT_DETAIL = CS_OPT_ON
|
||||
/// Initialized as memset(., 0, offsetof(cs_detail, ARCH)+sizeof(cs_ARCH))
|
||||
/// by ARCH_getInstruction in arch/ARCH/ARCHDisassembler.c
|
||||
/// if cs_detail changes, in particular if a field is added after the union,
|
||||
/// then update arch/ARCH/ARCHDisassembler.c accordingly
|
||||
typedef struct cs_detail {
|
||||
uint16_t regs_read[12]; ///< list of implicit registers read by this insn
|
||||
uint8_t regs_read_count; ///< number of implicit registers read by this insn
|
||||
|
||||
uint16_t regs_write[20]; ///< list of implicit registers modified by this insn
|
||||
uint8_t regs_write_count; ///< number of implicit registers modified by this insn
|
||||
|
||||
uint8_t groups[8]; ///< list of group this instruction belong to
|
||||
uint8_t groups_count; ///< number of groups this insn belongs to
|
||||
|
||||
/// Architecture-specific instruction info
|
||||
union {
|
||||
cs_x86 x86; ///< X86 architecture, including 16-bit, 32-bit & 64-bit mode
|
||||
cs_arm64 arm64; ///< ARM64 architecture (aka AArch64)
|
||||
cs_arm arm; ///< ARM architecture (including Thumb/Thumb2)
|
||||
cs_m68k m68k; ///< M68K architecture
|
||||
cs_mips mips; ///< MIPS architecture
|
||||
cs_ppc ppc; ///< PowerPC architecture
|
||||
cs_sparc sparc; ///< Sparc architecture
|
||||
cs_sysz sysz; ///< SystemZ architecture
|
||||
cs_xcore xcore; ///< XCore architecture
|
||||
cs_tms320c64x tms320c64x; ///< TMS320C64x architecture
|
||||
cs_m680x m680x; ///< M680X architecture
|
||||
cs_evm evm; ///< Ethereum architecture
|
||||
};
|
||||
} cs_detail;
|
||||
|
||||
/// Detail information of disassembled instruction
|
||||
typedef struct cs_insn {
|
||||
/// 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.
|
||||
unsigned int id;
|
||||
|
||||
/// Address (EIP) of this instruction
|
||||
/// This information is available even when CS_OPT_DETAIL = CS_OPT_OFF
|
||||
uint64_t address;
|
||||
|
||||
/// Size of this instruction
|
||||
/// This information is available even when CS_OPT_DETAIL = CS_OPT_OFF
|
||||
uint16_t size;
|
||||
|
||||
/// 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
|
||||
uint8_t bytes[16];
|
||||
|
||||
/// Ascii text of instruction mnemonic
|
||||
/// This information is available even when CS_OPT_DETAIL = CS_OPT_OFF
|
||||
char mnemonic[CS_MNEMONIC_SIZE];
|
||||
|
||||
/// Ascii text of instruction operands
|
||||
/// This information is available even when CS_OPT_DETAIL = CS_OPT_OFF
|
||||
char op_str[160];
|
||||
|
||||
/// Pointer to cs_detail.
|
||||
/// NOTE: detail pointer 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)
|
||||
///
|
||||
/// NOTE 2: when in Skipdata mode, or when detail mode is OFF, even if this pointer
|
||||
/// is not NULL, its content is still irrelevant.
|
||||
cs_detail *detail;
|
||||
} cs_insn;
|
||||
|
||||
|
||||
/// Calculate the offset of a disassembled instruction in its buffer, given its position
|
||||
/// in its array of disassembled insn
|
||||
/// NOTE: this macro works with position (>=1), not index
|
||||
#define CS_INSN_OFFSET(insns, post) (insns[post - 1].address - insns[0].address)
|
||||
|
||||
|
||||
/// All type of errors encountered by Capstone API.
|
||||
/// These are values returned by cs_errno()
|
||||
typedef enum cs_err {
|
||||
CS_ERR_OK = 0, ///< No error: everything was fine
|
||||
CS_ERR_MEM, ///< Out-Of-Memory error: cs_open(), cs_disasm(), cs_disasm_iter()
|
||||
CS_ERR_ARCH, ///< Unsupported architecture: cs_open()
|
||||
CS_ERR_HANDLE, ///< Invalid handle: cs_op_count(), cs_op_index()
|
||||
CS_ERR_CSH, ///< Invalid csh argument: cs_close(), cs_errno(), cs_option()
|
||||
CS_ERR_MODE, ///< Invalid/unsupported mode: cs_open()
|
||||
CS_ERR_OPTION, ///< Invalid/unsupported option: cs_option()
|
||||
CS_ERR_DETAIL, ///< Information is unavailable because detail option is OFF
|
||||
CS_ERR_MEMSETUP, ///< Dynamic memory management uninitialized (see CS_OPT_MEM)
|
||||
CS_ERR_VERSION, ///< Unsupported version (bindings)
|
||||
CS_ERR_DIET, ///< Access irrelevant data in "diet" engine
|
||||
CS_ERR_SKIPDATA, ///< Access irrelevant data for "data" instruction in SKIPDATA mode
|
||||
CS_ERR_X86_ATT, ///< X86 AT&T syntax is unsupported (opt-out at compile time)
|
||||
CS_ERR_X86_INTEL, ///< X86 Intel syntax is unsupported (opt-out at compile time)
|
||||
CS_ERR_X86_MASM, ///< X86 Intel syntax is unsupported (opt-out at compile time)
|
||||
} cs_err;
|
||||
|
||||
/**
|
||||
Return combined API version & major and minor version numbers.
|
||||
|
||||
@major: major number of API version
|
||||
@minor: minor number of API version
|
||||
|
||||
@return hexical number as (major << 8 | minor), which encodes both
|
||||
major & minor versions.
|
||||
NOTE: This returned value can be compared with version number made
|
||||
with macro CS_MAKE_VERSION
|
||||
|
||||
For example, second API version would return 1 in @major, and 1 in @minor
|
||||
The return value would be 0x0101
|
||||
|
||||
NOTE: if you only care about returned value, but not major and minor values,
|
||||
set both @major & @minor arguments to NULL.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
unsigned int CAPSTONE_API cs_version(int *major, int *minor);
|
||||
|
||||
|
||||
/**
|
||||
This API can be used to either ask for archs supported by this library,
|
||||
or check to see if the library was compile with 'diet' option (or called
|
||||
in 'diet' mode).
|
||||
|
||||
To check if a particular arch is supported by this library, set @query to
|
||||
arch mode (CS_ARCH_* value).
|
||||
To verify if this library supports all the archs, use CS_ARCH_ALL.
|
||||
|
||||
To check if this library is in 'diet' mode, set @query to CS_SUPPORT_DIET.
|
||||
|
||||
@return True if this library supports the given arch, or in 'diet' mode.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
bool CAPSTONE_API cs_support(int query);
|
||||
|
||||
/**
|
||||
Initialize CS handle: this must be done before any usage of CS.
|
||||
|
||||
@arch: architecture type (CS_ARCH_*)
|
||||
@mode: hardware mode. This is combined of CS_MODE_*
|
||||
@handle: pointer to handle, which will be updated at return time
|
||||
|
||||
@return CS_ERR_OK on success, or other value on failure (refer to cs_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
cs_err CAPSTONE_API cs_open(cs_arch arch, cs_mode mode, csh *handle);
|
||||
|
||||
/**
|
||||
Close CS handle: MUST do to release the handle when it is not used anymore.
|
||||
NOTE: this must be only called when there is no longer usage of Capstone,
|
||||
not even access to cs_insn array. The reason is the this API releases some
|
||||
cached memory, thus access to any Capstone API after cs_close() might crash
|
||||
your application.
|
||||
|
||||
In fact,this API invalidate @handle by ZERO out its value (i.e *handle = 0).
|
||||
|
||||
@handle: pointer to a handle returned by cs_open()
|
||||
|
||||
@return CS_ERR_OK on success, or other value on failure (refer to cs_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
cs_err CAPSTONE_API cs_close(csh *handle);
|
||||
|
||||
/**
|
||||
Set option for disassembling engine at runtime
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
@type: type of option to be set
|
||||
@value: option value corresponding with @type
|
||||
|
||||
@return: CS_ERR_OK on success, or other value on failure.
|
||||
Refer to cs_err enum for detailed error.
|
||||
|
||||
NOTE: in the case of CS_OPT_MEM, handle's value can be anything,
|
||||
so that cs_option(handle, CS_OPT_MEM, value) can (i.e must) be called
|
||||
even before cs_open()
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
cs_err CAPSTONE_API cs_option(csh handle, cs_opt_type type, size_t value);
|
||||
|
||||
/**
|
||||
Report the last error number when some API function fail.
|
||||
Like glibc's errno, cs_errno might not retain its old value once accessed.
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
|
||||
@return: error code of cs_err enum type (CS_ERR_*, see above)
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
cs_err CAPSTONE_API cs_errno(csh handle);
|
||||
|
||||
|
||||
/**
|
||||
Return a string describing given error code.
|
||||
|
||||
@code: error code (see CS_ERR_* above)
|
||||
|
||||
@return: returns a pointer to a string that describes the error code
|
||||
passed in the argument @code
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
const char * CAPSTONE_API cs_strerror(cs_err code);
|
||||
|
||||
/**
|
||||
Disassemble binary code, given the code buffer, size, address and number
|
||||
of instructions to be decoded.
|
||||
This API dynamically allocate memory to contain disassembled instruction.
|
||||
Resulting instructions will be put into @*insn
|
||||
|
||||
NOTE 1: this API will automatically determine memory needed to contain
|
||||
output disassembled instructions in @insn.
|
||||
|
||||
NOTE 2: caller must free the allocated memory itself to avoid memory leaking.
|
||||
|
||||
NOTE 3: for system with scarce memory to be dynamically allocated such as
|
||||
OS kernel or firmware, the API cs_disasm_iter() might be a better choice than
|
||||
cs_disasm(). The reason is that with cs_disasm(), based on limited available
|
||||
memory, we have to calculate in advance how many instructions to be disassembled,
|
||||
which complicates things. This is especially troublesome for the case @count=0,
|
||||
when cs_disasm() runs uncontrollably (until either end of input buffer, or
|
||||
when it encounters an invalid instruction).
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
@code: buffer containing raw binary code to be disassembled.
|
||||
@code_size: size of the above code buffer.
|
||||
@address: address of the first instruction in given raw code buffer.
|
||||
@insn: array of instructions filled in by this API.
|
||||
NOTE: @insn will be allocated by this function, and should be freed
|
||||
with cs_free() API.
|
||||
@count: number of instructions to be disassembled, or 0 to get all of them
|
||||
|
||||
@return: the number of successfully disassembled instructions,
|
||||
or 0 if this function failed to disassemble the given code
|
||||
|
||||
On failure, call cs_errno() for error code.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
size_t CAPSTONE_API cs_disasm(csh handle,
|
||||
const uint8_t *code, size_t code_size,
|
||||
uint64_t address,
|
||||
size_t count,
|
||||
cs_insn **insn);
|
||||
|
||||
/**
|
||||
Deprecated function - to be retired in the next version!
|
||||
Use cs_disasm() instead of cs_disasm_ex()
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
CAPSTONE_DEPRECATED
|
||||
size_t CAPSTONE_API cs_disasm_ex(csh handle,
|
||||
const uint8_t *code, size_t code_size,
|
||||
uint64_t address,
|
||||
size_t count,
|
||||
cs_insn **insn);
|
||||
|
||||
/**
|
||||
Free memory allocated by cs_malloc() or cs_disasm() (argument @insn)
|
||||
|
||||
@insn: pointer returned by @insn argument in cs_disasm() or cs_malloc()
|
||||
@count: number of cs_insn structures returned by cs_disasm(), or 1
|
||||
to free memory allocated by cs_malloc().
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
void CAPSTONE_API cs_free(cs_insn *insn, size_t count);
|
||||
|
||||
|
||||
/**
|
||||
Allocate memory for 1 instruction to be used by cs_disasm_iter().
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
|
||||
NOTE: when no longer in use, you can reclaim the memory allocated for
|
||||
this instruction with cs_free(insn, 1)
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
cs_insn * CAPSTONE_API cs_malloc(csh handle);
|
||||
|
||||
/**
|
||||
Fast API to disassemble binary code, given the code buffer, size, address
|
||||
and number of instructions to be decoded.
|
||||
This API puts the resulting instruction into a given cache in @insn.
|
||||
See tests/test_iter.c for sample code demonstrating this API.
|
||||
|
||||
NOTE 1: this API will update @code, @size & @address to point to the next
|
||||
instruction in the input buffer. Therefore, it is convenient to use
|
||||
cs_disasm_iter() inside a loop to quickly iterate all the instructions.
|
||||
While decoding one instruction at a time can also be achieved with
|
||||
cs_disasm(count=1), some benchmarks shown that cs_disasm_iter() can be 30%
|
||||
faster on random input.
|
||||
|
||||
NOTE 2: the cache in @insn can be created with cs_malloc() API.
|
||||
|
||||
NOTE 3: for system with scarce memory to be dynamically allocated such as
|
||||
OS kernel or firmware, this API is recommended over cs_disasm(), which
|
||||
allocates memory based on the number of instructions to be disassembled.
|
||||
The reason is that with cs_disasm(), based on limited available memory,
|
||||
we have to calculate in advance how many instructions to be disassembled,
|
||||
which complicates things. This is especially troublesome for the case
|
||||
@count=0, when cs_disasm() runs uncontrollably (until either end of input
|
||||
buffer, or when it encounters an invalid instruction).
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
@code: buffer containing raw binary code to be disassembled
|
||||
@size: size of above code
|
||||
@address: address of the first insn in given raw code buffer
|
||||
@insn: pointer to instruction to be filled in by this API.
|
||||
|
||||
@return: true if this API successfully decode 1 instruction,
|
||||
or false otherwise.
|
||||
|
||||
On failure, call cs_errno() for error code.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
bool CAPSTONE_API cs_disasm_iter(csh handle,
|
||||
const uint8_t **code, size_t *size,
|
||||
uint64_t *address, cs_insn *insn);
|
||||
|
||||
/**
|
||||
Return friendly name of register in a string.
|
||||
Find the instruction id from header file of corresponding architecture (arm.h for ARM,
|
||||
x86.h for X86, ...)
|
||||
|
||||
WARN: when in 'diet' mode, this API is irrelevant because engine does not
|
||||
store register name.
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
@reg_id: register id
|
||||
|
||||
@return: string name of the register, or NULL if @reg_id is invalid.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
const char * CAPSTONE_API cs_reg_name(csh handle, unsigned int reg_id);
|
||||
|
||||
/**
|
||||
Return friendly name of an instruction in a string.
|
||||
Find the instruction id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...)
|
||||
|
||||
WARN: when in 'diet' mode, this API is irrelevant because the engine does not
|
||||
store instruction name.
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
@insn_id: instruction id
|
||||
|
||||
@return: string name of the instruction, or NULL if @insn_id is invalid.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
const char * CAPSTONE_API cs_insn_name(csh handle, unsigned int insn_id);
|
||||
|
||||
/**
|
||||
Return friendly name of a group id (that an instruction can belong to)
|
||||
Find the group id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...)
|
||||
|
||||
WARN: when in 'diet' mode, this API is irrelevant because the engine does not
|
||||
store group name.
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
@group_id: group id
|
||||
|
||||
@return: string name of the group, or NULL if @group_id is invalid.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
const char * CAPSTONE_API cs_group_name(csh handle, unsigned int group_id);
|
||||
|
||||
/**
|
||||
Check if a disassembled instruction belong to a particular group.
|
||||
Find the group id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...)
|
||||
Internally, this simply verifies if @group_id matches any member of insn->groups array.
|
||||
|
||||
NOTE: this API is only valid when detail option is ON (which is OFF by default).
|
||||
|
||||
WARN: when in 'diet' mode, this API is irrelevant because the engine does not
|
||||
update @groups array.
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
@insn: disassembled instruction structure received from cs_disasm() or cs_disasm_iter()
|
||||
@group_id: group that you want to check if this instruction belong to.
|
||||
|
||||
@return: true if this instruction indeed belongs to the given group, or false otherwise.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
bool CAPSTONE_API cs_insn_group(csh handle, const cs_insn *insn, unsigned int group_id);
|
||||
|
||||
/**
|
||||
Check if a disassembled instruction IMPLICITLY used a particular register.
|
||||
Find the register id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...)
|
||||
Internally, this simply verifies if @reg_id matches any member of insn->regs_read array.
|
||||
|
||||
NOTE: this API is only valid when detail option is ON (which is OFF by default)
|
||||
|
||||
WARN: when in 'diet' mode, this API is irrelevant because the engine does not
|
||||
update @regs_read array.
|
||||
|
||||
@insn: disassembled instruction structure received from cs_disasm() or cs_disasm_iter()
|
||||
@reg_id: register that you want to check if this instruction used it.
|
||||
|
||||
@return: true if this instruction indeed implicitly used the given register, or false otherwise.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
bool CAPSTONE_API cs_reg_read(csh handle, const cs_insn *insn, unsigned int reg_id);
|
||||
|
||||
/**
|
||||
Check if a disassembled instruction IMPLICITLY modified a particular register.
|
||||
Find the register id from header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...)
|
||||
Internally, this simply verifies if @reg_id matches any member of insn->regs_write array.
|
||||
|
||||
NOTE: this API is only valid when detail option is ON (which is OFF by default)
|
||||
|
||||
WARN: when in 'diet' mode, this API is irrelevant because the engine does not
|
||||
update @regs_write array.
|
||||
|
||||
@insn: disassembled instruction structure received from cs_disasm() or cs_disasm_iter()
|
||||
@reg_id: register that you want to check if this instruction modified it.
|
||||
|
||||
@return: true if this instruction indeed implicitly modified the given register, or false otherwise.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
bool CAPSTONE_API cs_reg_write(csh handle, const cs_insn *insn, unsigned int reg_id);
|
||||
|
||||
/**
|
||||
Count the number of operands of a given type.
|
||||
Find the operand type in header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...)
|
||||
|
||||
NOTE: this API is only valid when detail option is ON (which is OFF by default)
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
@insn: disassembled instruction structure received from cs_disasm() or cs_disasm_iter()
|
||||
@op_type: Operand type to be found.
|
||||
|
||||
@return: number of operands of given type @op_type in instruction @insn,
|
||||
or -1 on failure.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
int CAPSTONE_API cs_op_count(csh handle, const cs_insn *insn, unsigned int op_type);
|
||||
|
||||
/**
|
||||
Retrieve the position of operand of given type in <arch>.operands[] array.
|
||||
Later, the operand can be accessed using the returned position.
|
||||
Find the operand type in header file of corresponding architecture (arm.h for ARM, x86.h for X86, ...)
|
||||
|
||||
NOTE: this API is only valid when detail option is ON (which is OFF by default)
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
@insn: disassembled instruction structure received from cs_disasm() or cs_disasm_iter()
|
||||
@op_type: Operand type to be found.
|
||||
@position: position of the operand to be found. This must be in the range
|
||||
[1, cs_op_count(handle, insn, op_type)]
|
||||
|
||||
@return: index of operand of given type @op_type in <arch>.operands[] array
|
||||
in instruction @insn, or -1 on failure.
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
int CAPSTONE_API cs_op_index(csh handle, const cs_insn *insn, unsigned int op_type,
|
||||
unsigned int position);
|
||||
|
||||
/// Type of array to keep the list of registers
|
||||
typedef uint16_t cs_regs[64];
|
||||
|
||||
/**
|
||||
Retrieve all the registers accessed by an instruction, either explicitly or
|
||||
implicitly.
|
||||
|
||||
WARN: when in 'diet' mode, this API is irrelevant because engine does not
|
||||
store registers.
|
||||
|
||||
@handle: handle returned by cs_open()
|
||||
@insn: disassembled instruction structure returned from cs_disasm() or cs_disasm_iter()
|
||||
@regs_read: on return, this array contains all registers read by instruction.
|
||||
@regs_read_count: number of registers kept inside @regs_read array.
|
||||
@regs_write: on return, this array contains all registers written by instruction.
|
||||
@regs_write_count: number of registers kept inside @regs_write array.
|
||||
|
||||
@return CS_ERR_OK on success, or other value on failure (refer to cs_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
CAPSTONE_EXPORT
|
||||
cs_err CAPSTONE_API cs_regs_access(csh handle, const cs_insn *insn,
|
||||
cs_regs regs_read, uint8_t *regs_read_count,
|
||||
cs_regs regs_write, uint8_t *regs_write_count);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,188 @@
|
||||
#ifndef CAPSTONE_EVM_H
|
||||
#define CAPSTONE_EVM_H
|
||||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2018 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
/// Instruction structure
|
||||
typedef struct cs_evm {
|
||||
unsigned char pop; ///< number of items popped from the stack
|
||||
unsigned char push; ///< number of items pushed into the stack
|
||||
unsigned int fee; ///< gas fee for the instruction
|
||||
} cs_evm;
|
||||
|
||||
/// EVM instruction
|
||||
typedef enum evm_insn {
|
||||
EVM_INS_STOP = 0,
|
||||
EVM_INS_ADD = 1,
|
||||
EVM_INS_MUL = 2,
|
||||
EVM_INS_SUB = 3,
|
||||
EVM_INS_DIV = 4,
|
||||
EVM_INS_SDIV = 5,
|
||||
EVM_INS_MOD = 6,
|
||||
EVM_INS_SMOD = 7,
|
||||
EVM_INS_ADDMOD = 8,
|
||||
EVM_INS_MULMOD = 9,
|
||||
EVM_INS_EXP = 10,
|
||||
EVM_INS_SIGNEXTEND = 11,
|
||||
EVM_INS_LT = 16,
|
||||
EVM_INS_GT = 17,
|
||||
EVM_INS_SLT = 18,
|
||||
EVM_INS_SGT = 19,
|
||||
EVM_INS_EQ = 20,
|
||||
EVM_INS_ISZERO = 21,
|
||||
EVM_INS_AND = 22,
|
||||
EVM_INS_OR = 23,
|
||||
EVM_INS_XOR = 24,
|
||||
EVM_INS_NOT = 25,
|
||||
EVM_INS_BYTE = 26,
|
||||
EVM_INS_SHA3 = 32,
|
||||
EVM_INS_ADDRESS = 48,
|
||||
EVM_INS_BALANCE = 49,
|
||||
EVM_INS_ORIGIN = 50,
|
||||
EVM_INS_CALLER = 51,
|
||||
EVM_INS_CALLVALUE = 52,
|
||||
EVM_INS_CALLDATALOAD = 53,
|
||||
EVM_INS_CALLDATASIZE = 54,
|
||||
EVM_INS_CALLDATACOPY = 55,
|
||||
EVM_INS_CODESIZE = 56,
|
||||
EVM_INS_CODECOPY = 57,
|
||||
EVM_INS_GASPRICE = 58,
|
||||
EVM_INS_EXTCODESIZE = 59,
|
||||
EVM_INS_EXTCODECOPY = 60,
|
||||
EVM_INS_RETURNDATASIZE = 61,
|
||||
EVM_INS_RETURNDATACOPY = 62,
|
||||
EVM_INS_BLOCKHASH = 64,
|
||||
EVM_INS_COINBASE = 65,
|
||||
EVM_INS_TIMESTAMP = 66,
|
||||
EVM_INS_NUMBER = 67,
|
||||
EVM_INS_DIFFICULTY = 68,
|
||||
EVM_INS_GASLIMIT = 69,
|
||||
EVM_INS_POP = 80,
|
||||
EVM_INS_MLOAD = 81,
|
||||
EVM_INS_MSTORE = 82,
|
||||
EVM_INS_MSTORE8 = 83,
|
||||
EVM_INS_SLOAD = 84,
|
||||
EVM_INS_SSTORE = 85,
|
||||
EVM_INS_JUMP = 86,
|
||||
EVM_INS_JUMPI = 87,
|
||||
EVM_INS_PC = 88,
|
||||
EVM_INS_MSIZE = 89,
|
||||
EVM_INS_GAS = 90,
|
||||
EVM_INS_JUMPDEST = 91,
|
||||
EVM_INS_PUSH1 = 96,
|
||||
EVM_INS_PUSH2 = 97,
|
||||
EVM_INS_PUSH3 = 98,
|
||||
EVM_INS_PUSH4 = 99,
|
||||
EVM_INS_PUSH5 = 100,
|
||||
EVM_INS_PUSH6 = 101,
|
||||
EVM_INS_PUSH7 = 102,
|
||||
EVM_INS_PUSH8 = 103,
|
||||
EVM_INS_PUSH9 = 104,
|
||||
EVM_INS_PUSH10 = 105,
|
||||
EVM_INS_PUSH11 = 106,
|
||||
EVM_INS_PUSH12 = 107,
|
||||
EVM_INS_PUSH13 = 108,
|
||||
EVM_INS_PUSH14 = 109,
|
||||
EVM_INS_PUSH15 = 110,
|
||||
EVM_INS_PUSH16 = 111,
|
||||
EVM_INS_PUSH17 = 112,
|
||||
EVM_INS_PUSH18 = 113,
|
||||
EVM_INS_PUSH19 = 114,
|
||||
EVM_INS_PUSH20 = 115,
|
||||
EVM_INS_PUSH21 = 116,
|
||||
EVM_INS_PUSH22 = 117,
|
||||
EVM_INS_PUSH23 = 118,
|
||||
EVM_INS_PUSH24 = 119,
|
||||
EVM_INS_PUSH25 = 120,
|
||||
EVM_INS_PUSH26 = 121,
|
||||
EVM_INS_PUSH27 = 122,
|
||||
EVM_INS_PUSH28 = 123,
|
||||
EVM_INS_PUSH29 = 124,
|
||||
EVM_INS_PUSH30 = 125,
|
||||
EVM_INS_PUSH31 = 126,
|
||||
EVM_INS_PUSH32 = 127,
|
||||
EVM_INS_DUP1 = 128,
|
||||
EVM_INS_DUP2 = 129,
|
||||
EVM_INS_DUP3 = 130,
|
||||
EVM_INS_DUP4 = 131,
|
||||
EVM_INS_DUP5 = 132,
|
||||
EVM_INS_DUP6 = 133,
|
||||
EVM_INS_DUP7 = 134,
|
||||
EVM_INS_DUP8 = 135,
|
||||
EVM_INS_DUP9 = 136,
|
||||
EVM_INS_DUP10 = 137,
|
||||
EVM_INS_DUP11 = 138,
|
||||
EVM_INS_DUP12 = 139,
|
||||
EVM_INS_DUP13 = 140,
|
||||
EVM_INS_DUP14 = 141,
|
||||
EVM_INS_DUP15 = 142,
|
||||
EVM_INS_DUP16 = 143,
|
||||
EVM_INS_SWAP1 = 144,
|
||||
EVM_INS_SWAP2 = 145,
|
||||
EVM_INS_SWAP3 = 146,
|
||||
EVM_INS_SWAP4 = 147,
|
||||
EVM_INS_SWAP5 = 148,
|
||||
EVM_INS_SWAP6 = 149,
|
||||
EVM_INS_SWAP7 = 150,
|
||||
EVM_INS_SWAP8 = 151,
|
||||
EVM_INS_SWAP9 = 152,
|
||||
EVM_INS_SWAP10 = 153,
|
||||
EVM_INS_SWAP11 = 154,
|
||||
EVM_INS_SWAP12 = 155,
|
||||
EVM_INS_SWAP13 = 156,
|
||||
EVM_INS_SWAP14 = 157,
|
||||
EVM_INS_SWAP15 = 158,
|
||||
EVM_INS_SWAP16 = 159,
|
||||
EVM_INS_LOG0 = 160,
|
||||
EVM_INS_LOG1 = 161,
|
||||
EVM_INS_LOG2 = 162,
|
||||
EVM_INS_LOG3 = 163,
|
||||
EVM_INS_LOG4 = 164,
|
||||
EVM_INS_CREATE = 240,
|
||||
EVM_INS_CALL = 241,
|
||||
EVM_INS_CALLCODE = 242,
|
||||
EVM_INS_RETURN = 243,
|
||||
EVM_INS_DELEGATECALL = 244,
|
||||
EVM_INS_CALLBLACKBOX = 245,
|
||||
EVM_INS_STATICCALL = 250,
|
||||
EVM_INS_REVERT = 253,
|
||||
EVM_INS_SUICIDE = 255,
|
||||
|
||||
EVM_INS_INVALID = 512,
|
||||
EVM_INS_ENDING, // <-- mark the end of the list of instructions
|
||||
} evm_insn;
|
||||
|
||||
/// Group of EVM instructions
|
||||
typedef enum evm_insn_group {
|
||||
EVM_GRP_INVALID = 0, ///< = CS_GRP_INVALID
|
||||
|
||||
EVM_GRP_JUMP, ///< all jump instructions
|
||||
|
||||
EVM_GRP_MATH = 8, ///< math instructions
|
||||
EVM_GRP_STACK_WRITE, ///< instructions write to stack
|
||||
EVM_GRP_STACK_READ, ///< instructions read from stack
|
||||
EVM_GRP_MEM_WRITE, ///< instructions write to memory
|
||||
EVM_GRP_MEM_READ, ///< instructions read from memory
|
||||
EVM_GRP_STORE_WRITE, ///< instructions write to storage
|
||||
EVM_GRP_STORE_READ, ///< instructions read from storage
|
||||
EVM_GRP_HALT, ///< instructions halt execution
|
||||
|
||||
EVM_GRP_ENDING, ///< <-- mark the end of the list of groups
|
||||
} evm_insn_group;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,537 @@
|
||||
#ifndef CAPSTONE_M680X_H
|
||||
#define CAPSTONE_M680X_H
|
||||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* M680X Backend by Wolfgang Schwotzer <wolfgang.schwotzer@gmx.net> 2017 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
#define M680X_OPERAND_COUNT 9
|
||||
|
||||
/// M680X registers and special registers
|
||||
typedef enum m680x_reg {
|
||||
M680X_REG_INVALID = 0,
|
||||
|
||||
M680X_REG_A, ///< M6800/1/2/3/9, HD6301/9
|
||||
M680X_REG_B, ///< M6800/1/2/3/9, HD6301/9
|
||||
M680X_REG_E, ///< HD6309
|
||||
M680X_REG_F, ///< HD6309
|
||||
M680X_REG_0, ///< HD6309
|
||||
|
||||
M680X_REG_D, ///< M6801/3/9, HD6301/9
|
||||
M680X_REG_W, ///< HD6309
|
||||
|
||||
M680X_REG_CC, ///< M6800/1/2/3/9, M6301/9
|
||||
M680X_REG_DP, ///< M6809/M6309
|
||||
M680X_REG_MD, ///< M6309
|
||||
|
||||
M680X_REG_HX, ///< M6808
|
||||
M680X_REG_H, ///< M6808
|
||||
M680X_REG_X, ///< M6800/1/2/3/9, M6301/9
|
||||
M680X_REG_Y, ///< M6809/M6309
|
||||
M680X_REG_S, ///< M6809/M6309
|
||||
M680X_REG_U, ///< M6809/M6309
|
||||
M680X_REG_V, ///< M6309
|
||||
|
||||
M680X_REG_Q, ///< M6309
|
||||
|
||||
M680X_REG_PC, ///< M6800/1/2/3/9, M6301/9
|
||||
|
||||
M680X_REG_TMP2, ///< CPU12
|
||||
M680X_REG_TMP3, ///< CPU12
|
||||
|
||||
M680X_REG_ENDING, ///< <-- mark the end of the list of registers
|
||||
} m680x_reg;
|
||||
|
||||
/// Operand type for instruction's operands
|
||||
typedef enum m680x_op_type {
|
||||
M680X_OP_INVALID = 0, ///< = CS_OP_INVALID (Uninitialized).
|
||||
M680X_OP_REGISTER, ///< = Register operand.
|
||||
M680X_OP_IMMEDIATE, ///< = Immediate operand.
|
||||
M680X_OP_INDEXED, ///< = Indexed addressing operand.
|
||||
M680X_OP_EXTENDED, ///< = Extended addressing operand.
|
||||
M680X_OP_DIRECT, ///< = Direct addressing operand.
|
||||
M680X_OP_RELATIVE, ///< = Relative addressing operand.
|
||||
M680X_OP_CONSTANT, ///< = constant operand (Displayed as number only).
|
||||
///< Used e.g. for a bit index or page number.
|
||||
} m680x_op_type;
|
||||
|
||||
// Supported bit values for mem.idx.offset_bits
|
||||
#define M680X_OFFSET_NONE 0
|
||||
#define M680X_OFFSET_BITS_5 5
|
||||
#define M680X_OFFSET_BITS_8 8
|
||||
#define M680X_OFFSET_BITS_9 9
|
||||
#define M680X_OFFSET_BITS_16 16
|
||||
|
||||
// Supported bit flags for mem.idx.flags
|
||||
// These flags can be combined
|
||||
#define M680X_IDX_INDIRECT 1
|
||||
#define M680X_IDX_NO_COMMA 2
|
||||
#define M680X_IDX_POST_INC_DEC 4
|
||||
|
||||
/// Instruction's operand referring to indexed addressing
|
||||
typedef struct m680x_op_idx {
|
||||
m680x_reg base_reg; ///< base register (or M680X_REG_INVALID if
|
||||
///< irrelevant)
|
||||
m680x_reg offset_reg; ///< offset register (or M680X_REG_INVALID if
|
||||
///< irrelevant)
|
||||
int16_t offset; ///< 5-,8- or 16-bit offset. See also offset_bits.
|
||||
uint16_t offset_addr; ///< = offset addr. if base_reg == M680X_REG_PC.
|
||||
///< calculated as offset + PC
|
||||
uint8_t offset_bits; ///< offset width in bits for indexed addressing
|
||||
int8_t inc_dec; ///< inc. or dec. value:
|
||||
///< 0: no inc-/decrement
|
||||
///< 1 .. 8: increment by 1 .. 8
|
||||
///< -1 .. -8: decrement by 1 .. 8
|
||||
///< if flag M680X_IDX_POST_INC_DEC set it is post
|
||||
///< inc-/decrement otherwise pre inc-/decrement
|
||||
uint8_t flags; ///< 8-bit flags (see above)
|
||||
} m680x_op_idx;
|
||||
|
||||
/// Instruction's memory operand referring to relative addressing (Bcc/LBcc)
|
||||
typedef struct m680x_op_rel {
|
||||
uint16_t address; ///< The absolute address.
|
||||
///< calculated as PC + offset. PC is the first
|
||||
///< address after the instruction.
|
||||
int16_t offset; ///< the offset/displacement value
|
||||
} m680x_op_rel;
|
||||
|
||||
/// Instruction's operand referring to extended addressing
|
||||
typedef struct m680x_op_ext {
|
||||
uint16_t address; ///< The absolute address
|
||||
bool indirect; ///< true if extended indirect addressing
|
||||
} m680x_op_ext;
|
||||
|
||||
/// Instruction operand
|
||||
typedef struct cs_m680x_op {
|
||||
m680x_op_type type;
|
||||
union {
|
||||
int32_t imm; ///< immediate value for IMM operand
|
||||
m680x_reg reg; ///< register value for REG operand
|
||||
m680x_op_idx idx; ///< Indexed addressing operand
|
||||
m680x_op_rel rel; ///< Relative address. operand (Bcc/LBcc)
|
||||
m680x_op_ext ext; ///< Extended address
|
||||
uint8_t direct_addr; ///<</ Direct address (lower 8-bit)
|
||||
uint8_t const_val; ///< constant value (bit index, page nr.)
|
||||
};
|
||||
uint8_t size; ///< size of this operand (in bytes)
|
||||
/// How is this operand accessed? (READ, WRITE or READ|WRITE)
|
||||
/// This field is combined of cs_ac_type.
|
||||
/// NOTE: this field is irrelevant if engine is compiled in DIET
|
||||
uint8_t access;
|
||||
} cs_m680x_op;
|
||||
|
||||
/// Group of M680X instructions
|
||||
typedef enum m680x_group_type {
|
||||
M680X_GRP_INVALID = 0, /// = CS_GRP_INVALID
|
||||
// Generic groups
|
||||
// all jump instructions (conditional+direct+indirect jumps)
|
||||
M680X_GRP_JUMP, ///< = CS_GRP_JUMP
|
||||
// all call instructions
|
||||
M680X_GRP_CALL, ///< = CS_GRP_CALL
|
||||
// all return instructions
|
||||
M680X_GRP_RET, ///< = CS_GRP_RET
|
||||
// all interrupt instructions (int+syscall)
|
||||
M680X_GRP_INT, ///< = CS_GRP_INT
|
||||
// all interrupt return instructions
|
||||
M680X_GRP_IRET, ///< = CS_GRP_IRET
|
||||
// all privileged instructions
|
||||
M680X_GRP_PRIV, ///< = CS_GRP_PRIVILEDGE; not used
|
||||
// all relative branching instructions
|
||||
M680X_GRP_BRAREL, ///< = CS_GRP_BRANCH_RELATIVE
|
||||
|
||||
// Architecture-specific groups
|
||||
M680X_GRP_ENDING, // <-- mark the end of the list of groups
|
||||
} m680x_group_type;
|
||||
|
||||
// M680X instruction flags:
|
||||
|
||||
/// The first (register) operand is part of the
|
||||
/// instruction mnemonic
|
||||
#define M680X_FIRST_OP_IN_MNEM 1
|
||||
/// The second (register) operand is part of the
|
||||
/// instruction mnemonic
|
||||
#define M680X_SECOND_OP_IN_MNEM 2
|
||||
|
||||
/// The M680X instruction and it's operands
|
||||
typedef struct cs_m680x {
|
||||
uint8_t flags; ///< See: M680X instruction flags
|
||||
uint8_t op_count; ///< number of operands for the instruction or 0
|
||||
cs_m680x_op operands[M680X_OPERAND_COUNT]; ///< operands for this insn.
|
||||
} cs_m680x;
|
||||
|
||||
/// M680X instruction IDs
|
||||
typedef enum m680x_insn {
|
||||
M680X_INS_INVLD = 0,
|
||||
M680X_INS_ABA, ///< M6800/1/2/3
|
||||
M680X_INS_ABX,
|
||||
M680X_INS_ABY,
|
||||
M680X_INS_ADC,
|
||||
M680X_INS_ADCA,
|
||||
M680X_INS_ADCB,
|
||||
M680X_INS_ADCD,
|
||||
M680X_INS_ADCR,
|
||||
M680X_INS_ADD,
|
||||
M680X_INS_ADDA,
|
||||
M680X_INS_ADDB,
|
||||
M680X_INS_ADDD,
|
||||
M680X_INS_ADDE,
|
||||
M680X_INS_ADDF,
|
||||
M680X_INS_ADDR,
|
||||
M680X_INS_ADDW,
|
||||
M680X_INS_AIM,
|
||||
M680X_INS_AIS,
|
||||
M680X_INS_AIX,
|
||||
M680X_INS_AND,
|
||||
M680X_INS_ANDA,
|
||||
M680X_INS_ANDB,
|
||||
M680X_INS_ANDCC,
|
||||
M680X_INS_ANDD,
|
||||
M680X_INS_ANDR,
|
||||
M680X_INS_ASL,
|
||||
M680X_INS_ASLA,
|
||||
M680X_INS_ASLB,
|
||||
M680X_INS_ASLD, ///< or LSLD
|
||||
M680X_INS_ASR,
|
||||
M680X_INS_ASRA,
|
||||
M680X_INS_ASRB,
|
||||
M680X_INS_ASRD,
|
||||
M680X_INS_ASRX,
|
||||
M680X_INS_BAND,
|
||||
M680X_INS_BCC, ///< or BHS
|
||||
M680X_INS_BCLR,
|
||||
M680X_INS_BCS, ///< or BLO
|
||||
M680X_INS_BEOR,
|
||||
M680X_INS_BEQ,
|
||||
M680X_INS_BGE,
|
||||
M680X_INS_BGND,
|
||||
M680X_INS_BGT,
|
||||
M680X_INS_BHCC,
|
||||
M680X_INS_BHCS,
|
||||
M680X_INS_BHI,
|
||||
M680X_INS_BIAND,
|
||||
M680X_INS_BIEOR,
|
||||
M680X_INS_BIH,
|
||||
M680X_INS_BIL,
|
||||
M680X_INS_BIOR,
|
||||
M680X_INS_BIT,
|
||||
M680X_INS_BITA,
|
||||
M680X_INS_BITB,
|
||||
M680X_INS_BITD,
|
||||
M680X_INS_BITMD,
|
||||
M680X_INS_BLE,
|
||||
M680X_INS_BLS,
|
||||
M680X_INS_BLT,
|
||||
M680X_INS_BMC,
|
||||
M680X_INS_BMI,
|
||||
M680X_INS_BMS,
|
||||
M680X_INS_BNE,
|
||||
M680X_INS_BOR,
|
||||
M680X_INS_BPL,
|
||||
M680X_INS_BRCLR,
|
||||
M680X_INS_BRSET,
|
||||
M680X_INS_BRA,
|
||||
M680X_INS_BRN,
|
||||
M680X_INS_BSET,
|
||||
M680X_INS_BSR,
|
||||
M680X_INS_BVC,
|
||||
M680X_INS_BVS,
|
||||
M680X_INS_CALL,
|
||||
M680X_INS_CBA, ///< M6800/1/2/3
|
||||
M680X_INS_CBEQ,
|
||||
M680X_INS_CBEQA,
|
||||
M680X_INS_CBEQX,
|
||||
M680X_INS_CLC, ///< M6800/1/2/3
|
||||
M680X_INS_CLI, ///< M6800/1/2/3
|
||||
M680X_INS_CLR,
|
||||
M680X_INS_CLRA,
|
||||
M680X_INS_CLRB,
|
||||
M680X_INS_CLRD,
|
||||
M680X_INS_CLRE,
|
||||
M680X_INS_CLRF,
|
||||
M680X_INS_CLRH,
|
||||
M680X_INS_CLRW,
|
||||
M680X_INS_CLRX,
|
||||
M680X_INS_CLV, ///< M6800/1/2/3
|
||||
M680X_INS_CMP,
|
||||
M680X_INS_CMPA,
|
||||
M680X_INS_CMPB,
|
||||
M680X_INS_CMPD,
|
||||
M680X_INS_CMPE,
|
||||
M680X_INS_CMPF,
|
||||
M680X_INS_CMPR,
|
||||
M680X_INS_CMPS,
|
||||
M680X_INS_CMPU,
|
||||
M680X_INS_CMPW,
|
||||
M680X_INS_CMPX,
|
||||
M680X_INS_CMPY,
|
||||
M680X_INS_COM,
|
||||
M680X_INS_COMA,
|
||||
M680X_INS_COMB,
|
||||
M680X_INS_COMD,
|
||||
M680X_INS_COME,
|
||||
M680X_INS_COMF,
|
||||
M680X_INS_COMW,
|
||||
M680X_INS_COMX,
|
||||
M680X_INS_CPD,
|
||||
M680X_INS_CPHX,
|
||||
M680X_INS_CPS,
|
||||
M680X_INS_CPX, ///< M6800/1/2/3
|
||||
M680X_INS_CPY,
|
||||
M680X_INS_CWAI,
|
||||
M680X_INS_DAA,
|
||||
M680X_INS_DBEQ,
|
||||
M680X_INS_DBNE,
|
||||
M680X_INS_DBNZ,
|
||||
M680X_INS_DBNZA,
|
||||
M680X_INS_DBNZX,
|
||||
M680X_INS_DEC,
|
||||
M680X_INS_DECA,
|
||||
M680X_INS_DECB,
|
||||
M680X_INS_DECD,
|
||||
M680X_INS_DECE,
|
||||
M680X_INS_DECF,
|
||||
M680X_INS_DECW,
|
||||
M680X_INS_DECX,
|
||||
M680X_INS_DES, ///< M6800/1/2/3
|
||||
M680X_INS_DEX, ///< M6800/1/2/3
|
||||
M680X_INS_DEY,
|
||||
M680X_INS_DIV,
|
||||
M680X_INS_DIVD,
|
||||
M680X_INS_DIVQ,
|
||||
M680X_INS_EDIV,
|
||||
M680X_INS_EDIVS,
|
||||
M680X_INS_EIM,
|
||||
M680X_INS_EMACS,
|
||||
M680X_INS_EMAXD,
|
||||
M680X_INS_EMAXM,
|
||||
M680X_INS_EMIND,
|
||||
M680X_INS_EMINM,
|
||||
M680X_INS_EMUL,
|
||||
M680X_INS_EMULS,
|
||||
M680X_INS_EOR,
|
||||
M680X_INS_EORA,
|
||||
M680X_INS_EORB,
|
||||
M680X_INS_EORD,
|
||||
M680X_INS_EORR,
|
||||
M680X_INS_ETBL,
|
||||
M680X_INS_EXG,
|
||||
M680X_INS_FDIV,
|
||||
M680X_INS_IBEQ,
|
||||
M680X_INS_IBNE,
|
||||
M680X_INS_IDIV,
|
||||
M680X_INS_IDIVS,
|
||||
M680X_INS_ILLGL,
|
||||
M680X_INS_INC,
|
||||
M680X_INS_INCA,
|
||||
M680X_INS_INCB,
|
||||
M680X_INS_INCD,
|
||||
M680X_INS_INCE,
|
||||
M680X_INS_INCF,
|
||||
M680X_INS_INCW,
|
||||
M680X_INS_INCX,
|
||||
M680X_INS_INS, ///< M6800/1/2/3
|
||||
M680X_INS_INX, ///< M6800/1/2/3
|
||||
M680X_INS_INY,
|
||||
M680X_INS_JMP,
|
||||
M680X_INS_JSR,
|
||||
M680X_INS_LBCC, ///< or LBHS
|
||||
M680X_INS_LBCS, ///< or LBLO
|
||||
M680X_INS_LBEQ,
|
||||
M680X_INS_LBGE,
|
||||
M680X_INS_LBGT,
|
||||
M680X_INS_LBHI,
|
||||
M680X_INS_LBLE,
|
||||
M680X_INS_LBLS,
|
||||
M680X_INS_LBLT,
|
||||
M680X_INS_LBMI,
|
||||
M680X_INS_LBNE,
|
||||
M680X_INS_LBPL,
|
||||
M680X_INS_LBRA,
|
||||
M680X_INS_LBRN,
|
||||
M680X_INS_LBSR,
|
||||
M680X_INS_LBVC,
|
||||
M680X_INS_LBVS,
|
||||
M680X_INS_LDA,
|
||||
M680X_INS_LDAA, ///< M6800/1/2/3
|
||||
M680X_INS_LDAB, ///< M6800/1/2/3
|
||||
M680X_INS_LDB,
|
||||
M680X_INS_LDBT,
|
||||
M680X_INS_LDD,
|
||||
M680X_INS_LDE,
|
||||
M680X_INS_LDF,
|
||||
M680X_INS_LDHX,
|
||||
M680X_INS_LDMD,
|
||||
M680X_INS_LDQ,
|
||||
M680X_INS_LDS,
|
||||
M680X_INS_LDU,
|
||||
M680X_INS_LDW,
|
||||
M680X_INS_LDX,
|
||||
M680X_INS_LDY,
|
||||
M680X_INS_LEAS,
|
||||
M680X_INS_LEAU,
|
||||
M680X_INS_LEAX,
|
||||
M680X_INS_LEAY,
|
||||
M680X_INS_LSL,
|
||||
M680X_INS_LSLA,
|
||||
M680X_INS_LSLB,
|
||||
M680X_INS_LSLD,
|
||||
M680X_INS_LSLX,
|
||||
M680X_INS_LSR,
|
||||
M680X_INS_LSRA,
|
||||
M680X_INS_LSRB,
|
||||
M680X_INS_LSRD, ///< or ASRD
|
||||
M680X_INS_LSRW,
|
||||
M680X_INS_LSRX,
|
||||
M680X_INS_MAXA,
|
||||
M680X_INS_MAXM,
|
||||
M680X_INS_MEM,
|
||||
M680X_INS_MINA,
|
||||
M680X_INS_MINM,
|
||||
M680X_INS_MOV,
|
||||
M680X_INS_MOVB,
|
||||
M680X_INS_MOVW,
|
||||
M680X_INS_MUL,
|
||||
M680X_INS_MULD,
|
||||
M680X_INS_NEG,
|
||||
M680X_INS_NEGA,
|
||||
M680X_INS_NEGB,
|
||||
M680X_INS_NEGD,
|
||||
M680X_INS_NEGX,
|
||||
M680X_INS_NOP,
|
||||
M680X_INS_NSA,
|
||||
M680X_INS_OIM,
|
||||
M680X_INS_ORA,
|
||||
M680X_INS_ORAA, ///< M6800/1/2/3
|
||||
M680X_INS_ORAB, ///< M6800/1/2/3
|
||||
M680X_INS_ORB,
|
||||
M680X_INS_ORCC,
|
||||
M680X_INS_ORD,
|
||||
M680X_INS_ORR,
|
||||
M680X_INS_PSHA, ///< M6800/1/2/3
|
||||
M680X_INS_PSHB, ///< M6800/1/2/3
|
||||
M680X_INS_PSHC,
|
||||
M680X_INS_PSHD,
|
||||
M680X_INS_PSHH,
|
||||
M680X_INS_PSHS,
|
||||
M680X_INS_PSHSW,
|
||||
M680X_INS_PSHU,
|
||||
M680X_INS_PSHUW,
|
||||
M680X_INS_PSHX, ///< M6800/1/2/3
|
||||
M680X_INS_PSHY,
|
||||
M680X_INS_PULA, ///< M6800/1/2/3
|
||||
M680X_INS_PULB, ///< M6800/1/2/3
|
||||
M680X_INS_PULC,
|
||||
M680X_INS_PULD,
|
||||
M680X_INS_PULH,
|
||||
M680X_INS_PULS,
|
||||
M680X_INS_PULSW,
|
||||
M680X_INS_PULU,
|
||||
M680X_INS_PULUW,
|
||||
M680X_INS_PULX, ///< M6800/1/2/3
|
||||
M680X_INS_PULY,
|
||||
M680X_INS_REV,
|
||||
M680X_INS_REVW,
|
||||
M680X_INS_ROL,
|
||||
M680X_INS_ROLA,
|
||||
M680X_INS_ROLB,
|
||||
M680X_INS_ROLD,
|
||||
M680X_INS_ROLW,
|
||||
M680X_INS_ROLX,
|
||||
M680X_INS_ROR,
|
||||
M680X_INS_RORA,
|
||||
M680X_INS_RORB,
|
||||
M680X_INS_RORD,
|
||||
M680X_INS_RORW,
|
||||
M680X_INS_RORX,
|
||||
M680X_INS_RSP,
|
||||
M680X_INS_RTC,
|
||||
M680X_INS_RTI,
|
||||
M680X_INS_RTS,
|
||||
M680X_INS_SBA, ///< M6800/1/2/3
|
||||
M680X_INS_SBC,
|
||||
M680X_INS_SBCA,
|
||||
M680X_INS_SBCB,
|
||||
M680X_INS_SBCD,
|
||||
M680X_INS_SBCR,
|
||||
M680X_INS_SEC,
|
||||
M680X_INS_SEI,
|
||||
M680X_INS_SEV,
|
||||
M680X_INS_SEX,
|
||||
M680X_INS_SEXW,
|
||||
M680X_INS_SLP,
|
||||
M680X_INS_STA,
|
||||
M680X_INS_STAA, ///< M6800/1/2/3
|
||||
M680X_INS_STAB, ///< M6800/1/2/3
|
||||
M680X_INS_STB,
|
||||
M680X_INS_STBT,
|
||||
M680X_INS_STD,
|
||||
M680X_INS_STE,
|
||||
M680X_INS_STF,
|
||||
M680X_INS_STOP,
|
||||
M680X_INS_STHX,
|
||||
M680X_INS_STQ,
|
||||
M680X_INS_STS,
|
||||
M680X_INS_STU,
|
||||
M680X_INS_STW,
|
||||
M680X_INS_STX,
|
||||
M680X_INS_STY,
|
||||
M680X_INS_SUB,
|
||||
M680X_INS_SUBA,
|
||||
M680X_INS_SUBB,
|
||||
M680X_INS_SUBD,
|
||||
M680X_INS_SUBE,
|
||||
M680X_INS_SUBF,
|
||||
M680X_INS_SUBR,
|
||||
M680X_INS_SUBW,
|
||||
M680X_INS_SWI,
|
||||
M680X_INS_SWI2,
|
||||
M680X_INS_SWI3,
|
||||
M680X_INS_SYNC,
|
||||
M680X_INS_TAB, ///< M6800/1/2/3
|
||||
M680X_INS_TAP, ///< M6800/1/2/3
|
||||
M680X_INS_TAX,
|
||||
M680X_INS_TBA, ///< M6800/1/2/3
|
||||
M680X_INS_TBEQ,
|
||||
M680X_INS_TBL,
|
||||
M680X_INS_TBNE,
|
||||
M680X_INS_TEST,
|
||||
M680X_INS_TFM,
|
||||
M680X_INS_TFR,
|
||||
M680X_INS_TIM,
|
||||
M680X_INS_TPA, ///< M6800/1/2/3
|
||||
M680X_INS_TST,
|
||||
M680X_INS_TSTA,
|
||||
M680X_INS_TSTB,
|
||||
M680X_INS_TSTD,
|
||||
M680X_INS_TSTE,
|
||||
M680X_INS_TSTF,
|
||||
M680X_INS_TSTW,
|
||||
M680X_INS_TSTX,
|
||||
M680X_INS_TSX, ///< M6800/1/2/3
|
||||
M680X_INS_TSY,
|
||||
M680X_INS_TXA,
|
||||
M680X_INS_TXS, ///< M6800/1/2/3
|
||||
M680X_INS_TYS,
|
||||
M680X_INS_WAI, ///< M6800/1/2/3
|
||||
M680X_INS_WAIT,
|
||||
M680X_INS_WAV,
|
||||
M680X_INS_WAVR,
|
||||
M680X_INS_XGDX, ///< HD6301
|
||||
M680X_INS_XGDY,
|
||||
M680X_INS_ENDING, // <-- mark the end of the list of instructions
|
||||
} m680x_insn;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,610 @@
|
||||
#ifndef CAPSTONE_M68K_H
|
||||
#define CAPSTONE_M68K_H
|
||||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Daniel Collin <daniel@collin.com>, 2015-2016 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
#define M68K_OPERAND_COUNT 4
|
||||
|
||||
/// M68K registers and special registers
|
||||
typedef enum m68k_reg {
|
||||
M68K_REG_INVALID = 0,
|
||||
|
||||
M68K_REG_D0,
|
||||
M68K_REG_D1,
|
||||
M68K_REG_D2,
|
||||
M68K_REG_D3,
|
||||
M68K_REG_D4,
|
||||
M68K_REG_D5,
|
||||
M68K_REG_D6,
|
||||
M68K_REG_D7,
|
||||
|
||||
M68K_REG_A0,
|
||||
M68K_REG_A1,
|
||||
M68K_REG_A2,
|
||||
M68K_REG_A3,
|
||||
M68K_REG_A4,
|
||||
M68K_REG_A5,
|
||||
M68K_REG_A6,
|
||||
M68K_REG_A7,
|
||||
|
||||
M68K_REG_FP0,
|
||||
M68K_REG_FP1,
|
||||
M68K_REG_FP2,
|
||||
M68K_REG_FP3,
|
||||
M68K_REG_FP4,
|
||||
M68K_REG_FP5,
|
||||
M68K_REG_FP6,
|
||||
M68K_REG_FP7,
|
||||
|
||||
M68K_REG_PC,
|
||||
|
||||
M68K_REG_SR,
|
||||
M68K_REG_CCR,
|
||||
M68K_REG_SFC,
|
||||
M68K_REG_DFC,
|
||||
M68K_REG_USP,
|
||||
M68K_REG_VBR,
|
||||
M68K_REG_CACR,
|
||||
M68K_REG_CAAR,
|
||||
M68K_REG_MSP,
|
||||
M68K_REG_ISP,
|
||||
M68K_REG_TC,
|
||||
M68K_REG_ITT0,
|
||||
M68K_REG_ITT1,
|
||||
M68K_REG_DTT0,
|
||||
M68K_REG_DTT1,
|
||||
M68K_REG_MMUSR,
|
||||
M68K_REG_URP,
|
||||
M68K_REG_SRP,
|
||||
|
||||
M68K_REG_FPCR,
|
||||
M68K_REG_FPSR,
|
||||
M68K_REG_FPIAR,
|
||||
|
||||
M68K_REG_ENDING, // <-- mark the end of the list of registers
|
||||
} m68k_reg;
|
||||
|
||||
/// M68K Addressing Modes
|
||||
typedef enum m68k_address_mode {
|
||||
M68K_AM_NONE = 0, ///< No address mode.
|
||||
|
||||
M68K_AM_REG_DIRECT_DATA, ///< Register Direct - Data
|
||||
M68K_AM_REG_DIRECT_ADDR, ///< Register Direct - Address
|
||||
|
||||
M68K_AM_REGI_ADDR, ///< Register Indirect - Address
|
||||
M68K_AM_REGI_ADDR_POST_INC, ///< Register Indirect - Address with Postincrement
|
||||
M68K_AM_REGI_ADDR_PRE_DEC, ///< Register Indirect - Address with Predecrement
|
||||
M68K_AM_REGI_ADDR_DISP, ///< Register Indirect - Address with Displacement
|
||||
|
||||
M68K_AM_AREGI_INDEX_8_BIT_DISP, ///< Address Register Indirect With Index- 8-bit displacement
|
||||
M68K_AM_AREGI_INDEX_BASE_DISP, ///< Address Register Indirect With Index- Base displacement
|
||||
|
||||
M68K_AM_MEMI_POST_INDEX, ///< Memory indirect - Postindex
|
||||
M68K_AM_MEMI_PRE_INDEX, ///< Memory indirect - Preindex
|
||||
|
||||
M68K_AM_PCI_DISP, ///< Program Counter Indirect - with Displacement
|
||||
|
||||
M68K_AM_PCI_INDEX_8_BIT_DISP, ///< Program Counter Indirect with Index - with 8-Bit Displacement
|
||||
M68K_AM_PCI_INDEX_BASE_DISP, ///< Program Counter Indirect with Index - with Base Displacement
|
||||
|
||||
M68K_AM_PC_MEMI_POST_INDEX, ///< Program Counter Memory Indirect - Postindexed
|
||||
M68K_AM_PC_MEMI_PRE_INDEX, ///< Program Counter Memory Indirect - Preindexed
|
||||
|
||||
M68K_AM_ABSOLUTE_DATA_SHORT, ///< Absolute Data Addressing - Short
|
||||
M68K_AM_ABSOLUTE_DATA_LONG, ///< Absolute Data Addressing - Long
|
||||
M68K_AM_IMMEDIATE, ///< Immediate value
|
||||
|
||||
M68K_AM_BRANCH_DISPLACEMENT, ///< Address as displacement from (PC+2) used by branches
|
||||
} m68k_address_mode;
|
||||
|
||||
/// Operand type for instruction's operands
|
||||
typedef enum m68k_op_type {
|
||||
M68K_OP_INVALID = 0, ///< = CS_OP_INVALID (Uninitialized).
|
||||
M68K_OP_REG, ///< = CS_OP_REG (Register operand).
|
||||
M68K_OP_IMM, ///< = CS_OP_IMM (Immediate operand).
|
||||
M68K_OP_MEM, ///< = CS_OP_MEM (Memory operand).
|
||||
M68K_OP_FP_SINGLE, ///< single precision Floating-Point operand
|
||||
M68K_OP_FP_DOUBLE, ///< double precision Floating-Point operand
|
||||
M68K_OP_REG_BITS, ///< Register bits move
|
||||
M68K_OP_REG_PAIR, ///< Register pair in the same op (upper 4 bits for first reg, lower for second)
|
||||
M68K_OP_BR_DISP, ///< Branch displacement
|
||||
} m68k_op_type;
|
||||
|
||||
/// Instruction's operand referring to memory
|
||||
/// This is associated with M68K_OP_MEM operand type above
|
||||
typedef struct m68k_op_mem {
|
||||
m68k_reg base_reg; ///< base register (or M68K_REG_INVALID if irrelevant)
|
||||
m68k_reg index_reg; ///< index register (or M68K_REG_INVALID if irrelevant)
|
||||
m68k_reg in_base_reg; ///< indirect base register (or M68K_REG_INVALID if irrelevant)
|
||||
uint32_t in_disp; ///< indirect displacement
|
||||
uint32_t out_disp; ///< other displacement
|
||||
int16_t disp; ///< displacement value
|
||||
uint8_t scale; ///< scale for index register
|
||||
uint8_t bitfield; ///< set to true if the two values below should be used
|
||||
uint8_t width; ///< used for bf* instructions
|
||||
uint8_t offset; ///< used for bf* instructions
|
||||
uint8_t index_size; ///< 0 = w, 1 = l
|
||||
} m68k_op_mem;
|
||||
|
||||
/// Operand type for instruction's operands
|
||||
typedef enum m68k_op_br_disp_size {
|
||||
M68K_OP_BR_DISP_SIZE_INVALID = 0, ///< = CS_OP_INVALID (Uninitialized).
|
||||
M68K_OP_BR_DISP_SIZE_BYTE = 1, ///< signed 8-bit displacement
|
||||
M68K_OP_BR_DISP_SIZE_WORD = 2, ///< signed 16-bit displacement
|
||||
M68K_OP_BR_DISP_SIZE_LONG = 4, ///< signed 32-bit displacement
|
||||
} m68k_op_br_disp_size;
|
||||
|
||||
typedef struct m68k_op_br_disp {
|
||||
int32_t disp; ///< displacement value
|
||||
uint8_t disp_size; ///< Size from m68k_op_br_disp_size type above
|
||||
} m68k_op_br_disp;
|
||||
|
||||
/// Instruction operand
|
||||
typedef struct cs_m68k_op {
|
||||
union {
|
||||
uint64_t imm; ///< immediate value for IMM operand
|
||||
double dimm; ///< double imm
|
||||
float simm; ///< float imm
|
||||
m68k_reg reg; ///< register value for REG operand
|
||||
struct { ///< register pair in one operand
|
||||
m68k_reg reg_0;
|
||||
m68k_reg reg_1;
|
||||
} reg_pair;
|
||||
};
|
||||
|
||||
m68k_op_mem mem; ///< data when operand is targeting memory
|
||||
m68k_op_br_disp br_disp; ///< data when operand is a branch displacement
|
||||
uint32_t register_bits; ///< register bits for movem etc. (always in d0-d7, a0-a7, fp0 - fp7 order)
|
||||
m68k_op_type type;
|
||||
m68k_address_mode address_mode; ///< M68K addressing mode for this op
|
||||
} cs_m68k_op;
|
||||
|
||||
/// Operation size of the CPU instructions
|
||||
typedef enum m68k_cpu_size {
|
||||
M68K_CPU_SIZE_NONE = 0, ///< unsized or unspecified
|
||||
M68K_CPU_SIZE_BYTE = 1, ///< 1 byte in size
|
||||
M68K_CPU_SIZE_WORD = 2, ///< 2 bytes in size
|
||||
M68K_CPU_SIZE_LONG = 4, ///< 4 bytes in size
|
||||
} m68k_cpu_size;
|
||||
|
||||
/// Operation size of the FPU instructions (Notice that FPU instruction can also use CPU sizes if needed)
|
||||
typedef enum m68k_fpu_size {
|
||||
M68K_FPU_SIZE_NONE = 0, ///< unsized like fsave/frestore
|
||||
M68K_FPU_SIZE_SINGLE = 4, ///< 4 byte in size (single float)
|
||||
M68K_FPU_SIZE_DOUBLE = 8, ///< 8 byte in size (double)
|
||||
M68K_FPU_SIZE_EXTENDED = 12, ///< 12 byte in size (extended real format)
|
||||
} m68k_fpu_size;
|
||||
|
||||
/// Type of size that is being used for the current instruction
|
||||
typedef enum m68k_size_type {
|
||||
M68K_SIZE_TYPE_INVALID = 0,
|
||||
|
||||
M68K_SIZE_TYPE_CPU,
|
||||
M68K_SIZE_TYPE_FPU,
|
||||
} m68k_size_type;
|
||||
|
||||
/// Operation size of the current instruction (NOT the actually size of instruction)
|
||||
typedef struct m68k_op_size {
|
||||
m68k_size_type type;
|
||||
union {
|
||||
m68k_cpu_size cpu_size;
|
||||
m68k_fpu_size fpu_size;
|
||||
};
|
||||
} m68k_op_size;
|
||||
|
||||
/// The M68K instruction and it's operands
|
||||
typedef struct cs_m68k {
|
||||
// Number of operands of this instruction or 0 when instruction has no operand.
|
||||
cs_m68k_op operands[M68K_OPERAND_COUNT]; ///< operands for this instruction.
|
||||
m68k_op_size op_size; ///< size of data operand works on in bytes (.b, .w, .l, etc)
|
||||
uint8_t op_count; ///< number of operands for the instruction
|
||||
} cs_m68k;
|
||||
|
||||
/// M68K instruction
|
||||
typedef enum m68k_insn {
|
||||
M68K_INS_INVALID = 0,
|
||||
|
||||
M68K_INS_ABCD,
|
||||
M68K_INS_ADD,
|
||||
M68K_INS_ADDA,
|
||||
M68K_INS_ADDI,
|
||||
M68K_INS_ADDQ,
|
||||
M68K_INS_ADDX,
|
||||
M68K_INS_AND,
|
||||
M68K_INS_ANDI,
|
||||
M68K_INS_ASL,
|
||||
M68K_INS_ASR,
|
||||
M68K_INS_BHS,
|
||||
M68K_INS_BLO,
|
||||
M68K_INS_BHI,
|
||||
M68K_INS_BLS,
|
||||
M68K_INS_BCC,
|
||||
M68K_INS_BCS,
|
||||
M68K_INS_BNE,
|
||||
M68K_INS_BEQ,
|
||||
M68K_INS_BVC,
|
||||
M68K_INS_BVS,
|
||||
M68K_INS_BPL,
|
||||
M68K_INS_BMI,
|
||||
M68K_INS_BGE,
|
||||
M68K_INS_BLT,
|
||||
M68K_INS_BGT,
|
||||
M68K_INS_BLE,
|
||||
M68K_INS_BRA,
|
||||
M68K_INS_BSR,
|
||||
M68K_INS_BCHG,
|
||||
M68K_INS_BCLR,
|
||||
M68K_INS_BSET,
|
||||
M68K_INS_BTST,
|
||||
M68K_INS_BFCHG,
|
||||
M68K_INS_BFCLR,
|
||||
M68K_INS_BFEXTS,
|
||||
M68K_INS_BFEXTU,
|
||||
M68K_INS_BFFFO,
|
||||
M68K_INS_BFINS,
|
||||
M68K_INS_BFSET,
|
||||
M68K_INS_BFTST,
|
||||
M68K_INS_BKPT,
|
||||
M68K_INS_CALLM,
|
||||
M68K_INS_CAS,
|
||||
M68K_INS_CAS2,
|
||||
M68K_INS_CHK,
|
||||
M68K_INS_CHK2,
|
||||
M68K_INS_CLR,
|
||||
M68K_INS_CMP,
|
||||
M68K_INS_CMPA,
|
||||
M68K_INS_CMPI,
|
||||
M68K_INS_CMPM,
|
||||
M68K_INS_CMP2,
|
||||
M68K_INS_CINVL,
|
||||
M68K_INS_CINVP,
|
||||
M68K_INS_CINVA,
|
||||
M68K_INS_CPUSHL,
|
||||
M68K_INS_CPUSHP,
|
||||
M68K_INS_CPUSHA,
|
||||
M68K_INS_DBT,
|
||||
M68K_INS_DBF,
|
||||
M68K_INS_DBHI,
|
||||
M68K_INS_DBLS,
|
||||
M68K_INS_DBCC,
|
||||
M68K_INS_DBCS,
|
||||
M68K_INS_DBNE,
|
||||
M68K_INS_DBEQ,
|
||||
M68K_INS_DBVC,
|
||||
M68K_INS_DBVS,
|
||||
M68K_INS_DBPL,
|
||||
M68K_INS_DBMI,
|
||||
M68K_INS_DBGE,
|
||||
M68K_INS_DBLT,
|
||||
M68K_INS_DBGT,
|
||||
M68K_INS_DBLE,
|
||||
M68K_INS_DBRA,
|
||||
M68K_INS_DIVS,
|
||||
M68K_INS_DIVSL,
|
||||
M68K_INS_DIVU,
|
||||
M68K_INS_DIVUL,
|
||||
M68K_INS_EOR,
|
||||
M68K_INS_EORI,
|
||||
M68K_INS_EXG,
|
||||
M68K_INS_EXT,
|
||||
M68K_INS_EXTB,
|
||||
M68K_INS_FABS,
|
||||
M68K_INS_FSABS,
|
||||
M68K_INS_FDABS,
|
||||
M68K_INS_FACOS,
|
||||
M68K_INS_FADD,
|
||||
M68K_INS_FSADD,
|
||||
M68K_INS_FDADD,
|
||||
M68K_INS_FASIN,
|
||||
M68K_INS_FATAN,
|
||||
M68K_INS_FATANH,
|
||||
M68K_INS_FBF,
|
||||
M68K_INS_FBEQ,
|
||||
M68K_INS_FBOGT,
|
||||
M68K_INS_FBOGE,
|
||||
M68K_INS_FBOLT,
|
||||
M68K_INS_FBOLE,
|
||||
M68K_INS_FBOGL,
|
||||
M68K_INS_FBOR,
|
||||
M68K_INS_FBUN,
|
||||
M68K_INS_FBUEQ,
|
||||
M68K_INS_FBUGT,
|
||||
M68K_INS_FBUGE,
|
||||
M68K_INS_FBULT,
|
||||
M68K_INS_FBULE,
|
||||
M68K_INS_FBNE,
|
||||
M68K_INS_FBT,
|
||||
M68K_INS_FBSF,
|
||||
M68K_INS_FBSEQ,
|
||||
M68K_INS_FBGT,
|
||||
M68K_INS_FBGE,
|
||||
M68K_INS_FBLT,
|
||||
M68K_INS_FBLE,
|
||||
M68K_INS_FBGL,
|
||||
M68K_INS_FBGLE,
|
||||
M68K_INS_FBNGLE,
|
||||
M68K_INS_FBNGL,
|
||||
M68K_INS_FBNLE,
|
||||
M68K_INS_FBNLT,
|
||||
M68K_INS_FBNGE,
|
||||
M68K_INS_FBNGT,
|
||||
M68K_INS_FBSNE,
|
||||
M68K_INS_FBST,
|
||||
M68K_INS_FCMP,
|
||||
M68K_INS_FCOS,
|
||||
M68K_INS_FCOSH,
|
||||
M68K_INS_FDBF,
|
||||
M68K_INS_FDBEQ,
|
||||
M68K_INS_FDBOGT,
|
||||
M68K_INS_FDBOGE,
|
||||
M68K_INS_FDBOLT,
|
||||
M68K_INS_FDBOLE,
|
||||
M68K_INS_FDBOGL,
|
||||
M68K_INS_FDBOR,
|
||||
M68K_INS_FDBUN,
|
||||
M68K_INS_FDBUEQ,
|
||||
M68K_INS_FDBUGT,
|
||||
M68K_INS_FDBUGE,
|
||||
M68K_INS_FDBULT,
|
||||
M68K_INS_FDBULE,
|
||||
M68K_INS_FDBNE,
|
||||
M68K_INS_FDBT,
|
||||
M68K_INS_FDBSF,
|
||||
M68K_INS_FDBSEQ,
|
||||
M68K_INS_FDBGT,
|
||||
M68K_INS_FDBGE,
|
||||
M68K_INS_FDBLT,
|
||||
M68K_INS_FDBLE,
|
||||
M68K_INS_FDBGL,
|
||||
M68K_INS_FDBGLE,
|
||||
M68K_INS_FDBNGLE,
|
||||
M68K_INS_FDBNGL,
|
||||
M68K_INS_FDBNLE,
|
||||
M68K_INS_FDBNLT,
|
||||
M68K_INS_FDBNGE,
|
||||
M68K_INS_FDBNGT,
|
||||
M68K_INS_FDBSNE,
|
||||
M68K_INS_FDBST,
|
||||
M68K_INS_FDIV,
|
||||
M68K_INS_FSDIV,
|
||||
M68K_INS_FDDIV,
|
||||
M68K_INS_FETOX,
|
||||
M68K_INS_FETOXM1,
|
||||
M68K_INS_FGETEXP,
|
||||
M68K_INS_FGETMAN,
|
||||
M68K_INS_FINT,
|
||||
M68K_INS_FINTRZ,
|
||||
M68K_INS_FLOG10,
|
||||
M68K_INS_FLOG2,
|
||||
M68K_INS_FLOGN,
|
||||
M68K_INS_FLOGNP1,
|
||||
M68K_INS_FMOD,
|
||||
M68K_INS_FMOVE,
|
||||
M68K_INS_FSMOVE,
|
||||
M68K_INS_FDMOVE,
|
||||
M68K_INS_FMOVECR,
|
||||
M68K_INS_FMOVEM,
|
||||
M68K_INS_FMUL,
|
||||
M68K_INS_FSMUL,
|
||||
M68K_INS_FDMUL,
|
||||
M68K_INS_FNEG,
|
||||
M68K_INS_FSNEG,
|
||||
M68K_INS_FDNEG,
|
||||
M68K_INS_FNOP,
|
||||
M68K_INS_FREM,
|
||||
M68K_INS_FRESTORE,
|
||||
M68K_INS_FSAVE,
|
||||
M68K_INS_FSCALE,
|
||||
M68K_INS_FSGLDIV,
|
||||
M68K_INS_FSGLMUL,
|
||||
M68K_INS_FSIN,
|
||||
M68K_INS_FSINCOS,
|
||||
M68K_INS_FSINH,
|
||||
M68K_INS_FSQRT,
|
||||
M68K_INS_FSSQRT,
|
||||
M68K_INS_FDSQRT,
|
||||
M68K_INS_FSF,
|
||||
M68K_INS_FSBEQ,
|
||||
M68K_INS_FSOGT,
|
||||
M68K_INS_FSOGE,
|
||||
M68K_INS_FSOLT,
|
||||
M68K_INS_FSOLE,
|
||||
M68K_INS_FSOGL,
|
||||
M68K_INS_FSOR,
|
||||
M68K_INS_FSUN,
|
||||
M68K_INS_FSUEQ,
|
||||
M68K_INS_FSUGT,
|
||||
M68K_INS_FSUGE,
|
||||
M68K_INS_FSULT,
|
||||
M68K_INS_FSULE,
|
||||
M68K_INS_FSNE,
|
||||
M68K_INS_FST,
|
||||
M68K_INS_FSSF,
|
||||
M68K_INS_FSSEQ,
|
||||
M68K_INS_FSGT,
|
||||
M68K_INS_FSGE,
|
||||
M68K_INS_FSLT,
|
||||
M68K_INS_FSLE,
|
||||
M68K_INS_FSGL,
|
||||
M68K_INS_FSGLE,
|
||||
M68K_INS_FSNGLE,
|
||||
M68K_INS_FSNGL,
|
||||
M68K_INS_FSNLE,
|
||||
M68K_INS_FSNLT,
|
||||
M68K_INS_FSNGE,
|
||||
M68K_INS_FSNGT,
|
||||
M68K_INS_FSSNE,
|
||||
M68K_INS_FSST,
|
||||
M68K_INS_FSUB,
|
||||
M68K_INS_FSSUB,
|
||||
M68K_INS_FDSUB,
|
||||
M68K_INS_FTAN,
|
||||
M68K_INS_FTANH,
|
||||
M68K_INS_FTENTOX,
|
||||
M68K_INS_FTRAPF,
|
||||
M68K_INS_FTRAPEQ,
|
||||
M68K_INS_FTRAPOGT,
|
||||
M68K_INS_FTRAPOGE,
|
||||
M68K_INS_FTRAPOLT,
|
||||
M68K_INS_FTRAPOLE,
|
||||
M68K_INS_FTRAPOGL,
|
||||
M68K_INS_FTRAPOR,
|
||||
M68K_INS_FTRAPUN,
|
||||
M68K_INS_FTRAPUEQ,
|
||||
M68K_INS_FTRAPUGT,
|
||||
M68K_INS_FTRAPUGE,
|
||||
M68K_INS_FTRAPULT,
|
||||
M68K_INS_FTRAPULE,
|
||||
M68K_INS_FTRAPNE,
|
||||
M68K_INS_FTRAPT,
|
||||
M68K_INS_FTRAPSF,
|
||||
M68K_INS_FTRAPSEQ,
|
||||
M68K_INS_FTRAPGT,
|
||||
M68K_INS_FTRAPGE,
|
||||
M68K_INS_FTRAPLT,
|
||||
M68K_INS_FTRAPLE,
|
||||
M68K_INS_FTRAPGL,
|
||||
M68K_INS_FTRAPGLE,
|
||||
M68K_INS_FTRAPNGLE,
|
||||
M68K_INS_FTRAPNGL,
|
||||
M68K_INS_FTRAPNLE,
|
||||
M68K_INS_FTRAPNLT,
|
||||
M68K_INS_FTRAPNGE,
|
||||
M68K_INS_FTRAPNGT,
|
||||
M68K_INS_FTRAPSNE,
|
||||
M68K_INS_FTRAPST,
|
||||
M68K_INS_FTST,
|
||||
M68K_INS_FTWOTOX,
|
||||
M68K_INS_HALT,
|
||||
M68K_INS_ILLEGAL,
|
||||
M68K_INS_JMP,
|
||||
M68K_INS_JSR,
|
||||
M68K_INS_LEA,
|
||||
M68K_INS_LINK,
|
||||
M68K_INS_LPSTOP,
|
||||
M68K_INS_LSL,
|
||||
M68K_INS_LSR,
|
||||
M68K_INS_MOVE,
|
||||
M68K_INS_MOVEA,
|
||||
M68K_INS_MOVEC,
|
||||
M68K_INS_MOVEM,
|
||||
M68K_INS_MOVEP,
|
||||
M68K_INS_MOVEQ,
|
||||
M68K_INS_MOVES,
|
||||
M68K_INS_MOVE16,
|
||||
M68K_INS_MULS,
|
||||
M68K_INS_MULU,
|
||||
M68K_INS_NBCD,
|
||||
M68K_INS_NEG,
|
||||
M68K_INS_NEGX,
|
||||
M68K_INS_NOP,
|
||||
M68K_INS_NOT,
|
||||
M68K_INS_OR,
|
||||
M68K_INS_ORI,
|
||||
M68K_INS_PACK,
|
||||
M68K_INS_PEA,
|
||||
M68K_INS_PFLUSH,
|
||||
M68K_INS_PFLUSHA,
|
||||
M68K_INS_PFLUSHAN,
|
||||
M68K_INS_PFLUSHN,
|
||||
M68K_INS_PLOADR,
|
||||
M68K_INS_PLOADW,
|
||||
M68K_INS_PLPAR,
|
||||
M68K_INS_PLPAW,
|
||||
M68K_INS_PMOVE,
|
||||
M68K_INS_PMOVEFD,
|
||||
M68K_INS_PTESTR,
|
||||
M68K_INS_PTESTW,
|
||||
M68K_INS_PULSE,
|
||||
M68K_INS_REMS,
|
||||
M68K_INS_REMU,
|
||||
M68K_INS_RESET,
|
||||
M68K_INS_ROL,
|
||||
M68K_INS_ROR,
|
||||
M68K_INS_ROXL,
|
||||
M68K_INS_ROXR,
|
||||
M68K_INS_RTD,
|
||||
M68K_INS_RTE,
|
||||
M68K_INS_RTM,
|
||||
M68K_INS_RTR,
|
||||
M68K_INS_RTS,
|
||||
M68K_INS_SBCD,
|
||||
M68K_INS_ST,
|
||||
M68K_INS_SF,
|
||||
M68K_INS_SHI,
|
||||
M68K_INS_SLS,
|
||||
M68K_INS_SCC,
|
||||
M68K_INS_SHS,
|
||||
M68K_INS_SCS,
|
||||
M68K_INS_SLO,
|
||||
M68K_INS_SNE,
|
||||
M68K_INS_SEQ,
|
||||
M68K_INS_SVC,
|
||||
M68K_INS_SVS,
|
||||
M68K_INS_SPL,
|
||||
M68K_INS_SMI,
|
||||
M68K_INS_SGE,
|
||||
M68K_INS_SLT,
|
||||
M68K_INS_SGT,
|
||||
M68K_INS_SLE,
|
||||
M68K_INS_STOP,
|
||||
M68K_INS_SUB,
|
||||
M68K_INS_SUBA,
|
||||
M68K_INS_SUBI,
|
||||
M68K_INS_SUBQ,
|
||||
M68K_INS_SUBX,
|
||||
M68K_INS_SWAP,
|
||||
M68K_INS_TAS,
|
||||
M68K_INS_TRAP,
|
||||
M68K_INS_TRAPV,
|
||||
M68K_INS_TRAPT,
|
||||
M68K_INS_TRAPF,
|
||||
M68K_INS_TRAPHI,
|
||||
M68K_INS_TRAPLS,
|
||||
M68K_INS_TRAPCC,
|
||||
M68K_INS_TRAPHS,
|
||||
M68K_INS_TRAPCS,
|
||||
M68K_INS_TRAPLO,
|
||||
M68K_INS_TRAPNE,
|
||||
M68K_INS_TRAPEQ,
|
||||
M68K_INS_TRAPVC,
|
||||
M68K_INS_TRAPVS,
|
||||
M68K_INS_TRAPPL,
|
||||
M68K_INS_TRAPMI,
|
||||
M68K_INS_TRAPGE,
|
||||
M68K_INS_TRAPLT,
|
||||
M68K_INS_TRAPGT,
|
||||
M68K_INS_TRAPLE,
|
||||
M68K_INS_TST,
|
||||
M68K_INS_UNLK,
|
||||
M68K_INS_UNPK,
|
||||
M68K_INS_ENDING, // <-- mark the end of the list of instructions
|
||||
} m68k_insn;
|
||||
|
||||
/// Group of M68K instructions
|
||||
typedef enum m68k_group_type {
|
||||
M68K_GRP_INVALID = 0, ///< CS_GRUP_INVALID
|
||||
M68K_GRP_JUMP, ///< = CS_GRP_JUMP
|
||||
M68K_GRP_RET = 3, ///< = CS_GRP_RET
|
||||
M68K_GRP_IRET = 5, ///< = CS_GRP_IRET
|
||||
M68K_GRP_BRANCH_RELATIVE = 7, ///< = CS_GRP_BRANCH_RELATIVE
|
||||
|
||||
M68K_GRP_ENDING,// <-- mark the end of the list of groups
|
||||
} m68k_group_type;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,956 @@
|
||||
#ifndef CAPSTONE_MIPS_H
|
||||
#define CAPSTONE_MIPS_H
|
||||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
// GCC MIPS toolchain has a default macro called "mips" which breaks
|
||||
// compilation
|
||||
#undef mips
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
/// Operand type for instruction's operands
|
||||
typedef enum mips_op_type {
|
||||
MIPS_OP_INVALID = 0, ///< = CS_OP_INVALID (Uninitialized).
|
||||
MIPS_OP_REG, ///< = CS_OP_REG (Register operand).
|
||||
MIPS_OP_IMM, ///< = CS_OP_IMM (Immediate operand).
|
||||
MIPS_OP_MEM, ///< = CS_OP_MEM (Memory operand).
|
||||
} mips_op_type;
|
||||
|
||||
/// MIPS registers
|
||||
typedef enum mips_reg {
|
||||
MIPS_REG_INVALID = 0,
|
||||
// General purpose registers
|
||||
MIPS_REG_PC,
|
||||
|
||||
MIPS_REG_0,
|
||||
MIPS_REG_1,
|
||||
MIPS_REG_2,
|
||||
MIPS_REG_3,
|
||||
MIPS_REG_4,
|
||||
MIPS_REG_5,
|
||||
MIPS_REG_6,
|
||||
MIPS_REG_7,
|
||||
MIPS_REG_8,
|
||||
MIPS_REG_9,
|
||||
MIPS_REG_10,
|
||||
MIPS_REG_11,
|
||||
MIPS_REG_12,
|
||||
MIPS_REG_13,
|
||||
MIPS_REG_14,
|
||||
MIPS_REG_15,
|
||||
MIPS_REG_16,
|
||||
MIPS_REG_17,
|
||||
MIPS_REG_18,
|
||||
MIPS_REG_19,
|
||||
MIPS_REG_20,
|
||||
MIPS_REG_21,
|
||||
MIPS_REG_22,
|
||||
MIPS_REG_23,
|
||||
MIPS_REG_24,
|
||||
MIPS_REG_25,
|
||||
MIPS_REG_26,
|
||||
MIPS_REG_27,
|
||||
MIPS_REG_28,
|
||||
MIPS_REG_29,
|
||||
MIPS_REG_30,
|
||||
MIPS_REG_31,
|
||||
|
||||
// DSP registers
|
||||
MIPS_REG_DSPCCOND,
|
||||
MIPS_REG_DSPCARRY,
|
||||
MIPS_REG_DSPEFI,
|
||||
MIPS_REG_DSPOUTFLAG,
|
||||
MIPS_REG_DSPOUTFLAG16_19,
|
||||
MIPS_REG_DSPOUTFLAG20,
|
||||
MIPS_REG_DSPOUTFLAG21,
|
||||
MIPS_REG_DSPOUTFLAG22,
|
||||
MIPS_REG_DSPOUTFLAG23,
|
||||
MIPS_REG_DSPPOS,
|
||||
MIPS_REG_DSPSCOUNT,
|
||||
|
||||
// ACC registers
|
||||
MIPS_REG_AC0,
|
||||
MIPS_REG_AC1,
|
||||
MIPS_REG_AC2,
|
||||
MIPS_REG_AC3,
|
||||
|
||||
// COP registers
|
||||
MIPS_REG_CC0,
|
||||
MIPS_REG_CC1,
|
||||
MIPS_REG_CC2,
|
||||
MIPS_REG_CC3,
|
||||
MIPS_REG_CC4,
|
||||
MIPS_REG_CC5,
|
||||
MIPS_REG_CC6,
|
||||
MIPS_REG_CC7,
|
||||
|
||||
// FPU registers
|
||||
MIPS_REG_F0,
|
||||
MIPS_REG_F1,
|
||||
MIPS_REG_F2,
|
||||
MIPS_REG_F3,
|
||||
MIPS_REG_F4,
|
||||
MIPS_REG_F5,
|
||||
MIPS_REG_F6,
|
||||
MIPS_REG_F7,
|
||||
MIPS_REG_F8,
|
||||
MIPS_REG_F9,
|
||||
MIPS_REG_F10,
|
||||
MIPS_REG_F11,
|
||||
MIPS_REG_F12,
|
||||
MIPS_REG_F13,
|
||||
MIPS_REG_F14,
|
||||
MIPS_REG_F15,
|
||||
MIPS_REG_F16,
|
||||
MIPS_REG_F17,
|
||||
MIPS_REG_F18,
|
||||
MIPS_REG_F19,
|
||||
MIPS_REG_F20,
|
||||
MIPS_REG_F21,
|
||||
MIPS_REG_F22,
|
||||
MIPS_REG_F23,
|
||||
MIPS_REG_F24,
|
||||
MIPS_REG_F25,
|
||||
MIPS_REG_F26,
|
||||
MIPS_REG_F27,
|
||||
MIPS_REG_F28,
|
||||
MIPS_REG_F29,
|
||||
MIPS_REG_F30,
|
||||
MIPS_REG_F31,
|
||||
|
||||
MIPS_REG_FCC0,
|
||||
MIPS_REG_FCC1,
|
||||
MIPS_REG_FCC2,
|
||||
MIPS_REG_FCC3,
|
||||
MIPS_REG_FCC4,
|
||||
MIPS_REG_FCC5,
|
||||
MIPS_REG_FCC6,
|
||||
MIPS_REG_FCC7,
|
||||
|
||||
// AFPR128
|
||||
MIPS_REG_W0,
|
||||
MIPS_REG_W1,
|
||||
MIPS_REG_W2,
|
||||
MIPS_REG_W3,
|
||||
MIPS_REG_W4,
|
||||
MIPS_REG_W5,
|
||||
MIPS_REG_W6,
|
||||
MIPS_REG_W7,
|
||||
MIPS_REG_W8,
|
||||
MIPS_REG_W9,
|
||||
MIPS_REG_W10,
|
||||
MIPS_REG_W11,
|
||||
MIPS_REG_W12,
|
||||
MIPS_REG_W13,
|
||||
MIPS_REG_W14,
|
||||
MIPS_REG_W15,
|
||||
MIPS_REG_W16,
|
||||
MIPS_REG_W17,
|
||||
MIPS_REG_W18,
|
||||
MIPS_REG_W19,
|
||||
MIPS_REG_W20,
|
||||
MIPS_REG_W21,
|
||||
MIPS_REG_W22,
|
||||
MIPS_REG_W23,
|
||||
MIPS_REG_W24,
|
||||
MIPS_REG_W25,
|
||||
MIPS_REG_W26,
|
||||
MIPS_REG_W27,
|
||||
MIPS_REG_W28,
|
||||
MIPS_REG_W29,
|
||||
MIPS_REG_W30,
|
||||
MIPS_REG_W31,
|
||||
|
||||
MIPS_REG_HI,
|
||||
MIPS_REG_LO,
|
||||
|
||||
MIPS_REG_P0,
|
||||
MIPS_REG_P1,
|
||||
MIPS_REG_P2,
|
||||
|
||||
MIPS_REG_MPL0,
|
||||
MIPS_REG_MPL1,
|
||||
MIPS_REG_MPL2,
|
||||
|
||||
MIPS_REG_ENDING, // <-- mark the end of the list or registers
|
||||
|
||||
// alias registers
|
||||
MIPS_REG_ZERO = MIPS_REG_0,
|
||||
MIPS_REG_AT = MIPS_REG_1,
|
||||
MIPS_REG_V0 = MIPS_REG_2,
|
||||
MIPS_REG_V1 = MIPS_REG_3,
|
||||
MIPS_REG_A0 = MIPS_REG_4,
|
||||
MIPS_REG_A1 = MIPS_REG_5,
|
||||
MIPS_REG_A2 = MIPS_REG_6,
|
||||
MIPS_REG_A3 = MIPS_REG_7,
|
||||
MIPS_REG_T0 = MIPS_REG_8,
|
||||
MIPS_REG_T1 = MIPS_REG_9,
|
||||
MIPS_REG_T2 = MIPS_REG_10,
|
||||
MIPS_REG_T3 = MIPS_REG_11,
|
||||
MIPS_REG_T4 = MIPS_REG_12,
|
||||
MIPS_REG_T5 = MIPS_REG_13,
|
||||
MIPS_REG_T6 = MIPS_REG_14,
|
||||
MIPS_REG_T7 = MIPS_REG_15,
|
||||
MIPS_REG_S0 = MIPS_REG_16,
|
||||
MIPS_REG_S1 = MIPS_REG_17,
|
||||
MIPS_REG_S2 = MIPS_REG_18,
|
||||
MIPS_REG_S3 = MIPS_REG_19,
|
||||
MIPS_REG_S4 = MIPS_REG_20,
|
||||
MIPS_REG_S5 = MIPS_REG_21,
|
||||
MIPS_REG_S6 = MIPS_REG_22,
|
||||
MIPS_REG_S7 = MIPS_REG_23,
|
||||
MIPS_REG_T8 = MIPS_REG_24,
|
||||
MIPS_REG_T9 = MIPS_REG_25,
|
||||
MIPS_REG_K0 = MIPS_REG_26,
|
||||
MIPS_REG_K1 = MIPS_REG_27,
|
||||
MIPS_REG_GP = MIPS_REG_28,
|
||||
MIPS_REG_SP = MIPS_REG_29,
|
||||
MIPS_REG_FP = MIPS_REG_30, MIPS_REG_S8 = MIPS_REG_30,
|
||||
MIPS_REG_RA = MIPS_REG_31,
|
||||
|
||||
MIPS_REG_HI0 = MIPS_REG_AC0,
|
||||
MIPS_REG_HI1 = MIPS_REG_AC1,
|
||||
MIPS_REG_HI2 = MIPS_REG_AC2,
|
||||
MIPS_REG_HI3 = MIPS_REG_AC3,
|
||||
|
||||
MIPS_REG_LO0 = MIPS_REG_HI0,
|
||||
MIPS_REG_LO1 = MIPS_REG_HI1,
|
||||
MIPS_REG_LO2 = MIPS_REG_HI2,
|
||||
MIPS_REG_LO3 = MIPS_REG_HI3,
|
||||
} mips_reg;
|
||||
|
||||
/// Instruction's operand referring to memory
|
||||
/// This is associated with MIPS_OP_MEM operand type above
|
||||
typedef struct mips_op_mem {
|
||||
mips_reg base; ///< base register
|
||||
int64_t disp; ///< displacement/offset value
|
||||
} mips_op_mem;
|
||||
|
||||
/// Instruction operand
|
||||
typedef struct cs_mips_op {
|
||||
mips_op_type type; ///< operand type
|
||||
union {
|
||||
mips_reg reg; ///< register value for REG operand
|
||||
int64_t imm; ///< immediate value for IMM operand
|
||||
mips_op_mem mem; ///< base/index/scale/disp value for MEM operand
|
||||
};
|
||||
} cs_mips_op;
|
||||
|
||||
/// Instruction structure
|
||||
typedef struct cs_mips {
|
||||
/// Number of operands of this instruction,
|
||||
/// or 0 when instruction has no operand.
|
||||
uint8_t op_count;
|
||||
cs_mips_op operands[10]; ///< operands for this instruction.
|
||||
} cs_mips;
|
||||
|
||||
/// MIPS instruction
|
||||
typedef enum mips_insn {
|
||||
MIPS_INS_INVALID = 0,
|
||||
|
||||
MIPS_INS_ABSQ_S,
|
||||
MIPS_INS_ADD,
|
||||
MIPS_INS_ADDIUPC,
|
||||
MIPS_INS_ADDIUR1SP,
|
||||
MIPS_INS_ADDIUR2,
|
||||
MIPS_INS_ADDIUS5,
|
||||
MIPS_INS_ADDIUSP,
|
||||
MIPS_INS_ADDQH,
|
||||
MIPS_INS_ADDQH_R,
|
||||
MIPS_INS_ADDQ,
|
||||
MIPS_INS_ADDQ_S,
|
||||
MIPS_INS_ADDSC,
|
||||
MIPS_INS_ADDS_A,
|
||||
MIPS_INS_ADDS_S,
|
||||
MIPS_INS_ADDS_U,
|
||||
MIPS_INS_ADDU16,
|
||||
MIPS_INS_ADDUH,
|
||||
MIPS_INS_ADDUH_R,
|
||||
MIPS_INS_ADDU,
|
||||
MIPS_INS_ADDU_S,
|
||||
MIPS_INS_ADDVI,
|
||||
MIPS_INS_ADDV,
|
||||
MIPS_INS_ADDWC,
|
||||
MIPS_INS_ADD_A,
|
||||
MIPS_INS_ADDI,
|
||||
MIPS_INS_ADDIU,
|
||||
MIPS_INS_ALIGN,
|
||||
MIPS_INS_ALUIPC,
|
||||
MIPS_INS_AND,
|
||||
MIPS_INS_AND16,
|
||||
MIPS_INS_ANDI16,
|
||||
MIPS_INS_ANDI,
|
||||
MIPS_INS_APPEND,
|
||||
MIPS_INS_ASUB_S,
|
||||
MIPS_INS_ASUB_U,
|
||||
MIPS_INS_AUI,
|
||||
MIPS_INS_AUIPC,
|
||||
MIPS_INS_AVER_S,
|
||||
MIPS_INS_AVER_U,
|
||||
MIPS_INS_AVE_S,
|
||||
MIPS_INS_AVE_U,
|
||||
MIPS_INS_B16,
|
||||
MIPS_INS_BADDU,
|
||||
MIPS_INS_BAL,
|
||||
MIPS_INS_BALC,
|
||||
MIPS_INS_BALIGN,
|
||||
MIPS_INS_BBIT0,
|
||||
MIPS_INS_BBIT032,
|
||||
MIPS_INS_BBIT1,
|
||||
MIPS_INS_BBIT132,
|
||||
MIPS_INS_BC,
|
||||
MIPS_INS_BC0F,
|
||||
MIPS_INS_BC0FL,
|
||||
MIPS_INS_BC0T,
|
||||
MIPS_INS_BC0TL,
|
||||
MIPS_INS_BC1EQZ,
|
||||
MIPS_INS_BC1F,
|
||||
MIPS_INS_BC1FL,
|
||||
MIPS_INS_BC1NEZ,
|
||||
MIPS_INS_BC1T,
|
||||
MIPS_INS_BC1TL,
|
||||
MIPS_INS_BC2EQZ,
|
||||
MIPS_INS_BC2F,
|
||||
MIPS_INS_BC2FL,
|
||||
MIPS_INS_BC2NEZ,
|
||||
MIPS_INS_BC2T,
|
||||
MIPS_INS_BC2TL,
|
||||
MIPS_INS_BC3F,
|
||||
MIPS_INS_BC3FL,
|
||||
MIPS_INS_BC3T,
|
||||
MIPS_INS_BC3TL,
|
||||
MIPS_INS_BCLRI,
|
||||
MIPS_INS_BCLR,
|
||||
MIPS_INS_BEQ,
|
||||
MIPS_INS_BEQC,
|
||||
MIPS_INS_BEQL,
|
||||
MIPS_INS_BEQZ16,
|
||||
MIPS_INS_BEQZALC,
|
||||
MIPS_INS_BEQZC,
|
||||
MIPS_INS_BGEC,
|
||||
MIPS_INS_BGEUC,
|
||||
MIPS_INS_BGEZ,
|
||||
MIPS_INS_BGEZAL,
|
||||
MIPS_INS_BGEZALC,
|
||||
MIPS_INS_BGEZALL,
|
||||
MIPS_INS_BGEZALS,
|
||||
MIPS_INS_BGEZC,
|
||||
MIPS_INS_BGEZL,
|
||||
MIPS_INS_BGTZ,
|
||||
MIPS_INS_BGTZALC,
|
||||
MIPS_INS_BGTZC,
|
||||
MIPS_INS_BGTZL,
|
||||
MIPS_INS_BINSLI,
|
||||
MIPS_INS_BINSL,
|
||||
MIPS_INS_BINSRI,
|
||||
MIPS_INS_BINSR,
|
||||
MIPS_INS_BITREV,
|
||||
MIPS_INS_BITSWAP,
|
||||
MIPS_INS_BLEZ,
|
||||
MIPS_INS_BLEZALC,
|
||||
MIPS_INS_BLEZC,
|
||||
MIPS_INS_BLEZL,
|
||||
MIPS_INS_BLTC,
|
||||
MIPS_INS_BLTUC,
|
||||
MIPS_INS_BLTZ,
|
||||
MIPS_INS_BLTZAL,
|
||||
MIPS_INS_BLTZALC,
|
||||
MIPS_INS_BLTZALL,
|
||||
MIPS_INS_BLTZALS,
|
||||
MIPS_INS_BLTZC,
|
||||
MIPS_INS_BLTZL,
|
||||
MIPS_INS_BMNZI,
|
||||
MIPS_INS_BMNZ,
|
||||
MIPS_INS_BMZI,
|
||||
MIPS_INS_BMZ,
|
||||
MIPS_INS_BNE,
|
||||
MIPS_INS_BNEC,
|
||||
MIPS_INS_BNEGI,
|
||||
MIPS_INS_BNEG,
|
||||
MIPS_INS_BNEL,
|
||||
MIPS_INS_BNEZ16,
|
||||
MIPS_INS_BNEZALC,
|
||||
MIPS_INS_BNEZC,
|
||||
MIPS_INS_BNVC,
|
||||
MIPS_INS_BNZ,
|
||||
MIPS_INS_BOVC,
|
||||
MIPS_INS_BPOSGE32,
|
||||
MIPS_INS_BREAK,
|
||||
MIPS_INS_BREAK16,
|
||||
MIPS_INS_BSELI,
|
||||
MIPS_INS_BSEL,
|
||||
MIPS_INS_BSETI,
|
||||
MIPS_INS_BSET,
|
||||
MIPS_INS_BZ,
|
||||
MIPS_INS_BEQZ,
|
||||
MIPS_INS_B,
|
||||
MIPS_INS_BNEZ,
|
||||
MIPS_INS_BTEQZ,
|
||||
MIPS_INS_BTNEZ,
|
||||
MIPS_INS_CACHE,
|
||||
MIPS_INS_CEIL,
|
||||
MIPS_INS_CEQI,
|
||||
MIPS_INS_CEQ,
|
||||
MIPS_INS_CFC1,
|
||||
MIPS_INS_CFCMSA,
|
||||
MIPS_INS_CINS,
|
||||
MIPS_INS_CINS32,
|
||||
MIPS_INS_CLASS,
|
||||
MIPS_INS_CLEI_S,
|
||||
MIPS_INS_CLEI_U,
|
||||
MIPS_INS_CLE_S,
|
||||
MIPS_INS_CLE_U,
|
||||
MIPS_INS_CLO,
|
||||
MIPS_INS_CLTI_S,
|
||||
MIPS_INS_CLTI_U,
|
||||
MIPS_INS_CLT_S,
|
||||
MIPS_INS_CLT_U,
|
||||
MIPS_INS_CLZ,
|
||||
MIPS_INS_CMPGDU,
|
||||
MIPS_INS_CMPGU,
|
||||
MIPS_INS_CMPU,
|
||||
MIPS_INS_CMP,
|
||||
MIPS_INS_COPY_S,
|
||||
MIPS_INS_COPY_U,
|
||||
MIPS_INS_CTC1,
|
||||
MIPS_INS_CTCMSA,
|
||||
MIPS_INS_CVT,
|
||||
MIPS_INS_C,
|
||||
MIPS_INS_CMPI,
|
||||
MIPS_INS_DADD,
|
||||
MIPS_INS_DADDI,
|
||||
MIPS_INS_DADDIU,
|
||||
MIPS_INS_DADDU,
|
||||
MIPS_INS_DAHI,
|
||||
MIPS_INS_DALIGN,
|
||||
MIPS_INS_DATI,
|
||||
MIPS_INS_DAUI,
|
||||
MIPS_INS_DBITSWAP,
|
||||
MIPS_INS_DCLO,
|
||||
MIPS_INS_DCLZ,
|
||||
MIPS_INS_DDIV,
|
||||
MIPS_INS_DDIVU,
|
||||
MIPS_INS_DERET,
|
||||
MIPS_INS_DEXT,
|
||||
MIPS_INS_DEXTM,
|
||||
MIPS_INS_DEXTU,
|
||||
MIPS_INS_DI,
|
||||
MIPS_INS_DINS,
|
||||
MIPS_INS_DINSM,
|
||||
MIPS_INS_DINSU,
|
||||
MIPS_INS_DIV,
|
||||
MIPS_INS_DIVU,
|
||||
MIPS_INS_DIV_S,
|
||||
MIPS_INS_DIV_U,
|
||||
MIPS_INS_DLSA,
|
||||
MIPS_INS_DMFC0,
|
||||
MIPS_INS_DMFC1,
|
||||
MIPS_INS_DMFC2,
|
||||
MIPS_INS_DMOD,
|
||||
MIPS_INS_DMODU,
|
||||
MIPS_INS_DMTC0,
|
||||
MIPS_INS_DMTC1,
|
||||
MIPS_INS_DMTC2,
|
||||
MIPS_INS_DMUH,
|
||||
MIPS_INS_DMUHU,
|
||||
MIPS_INS_DMUL,
|
||||
MIPS_INS_DMULT,
|
||||
MIPS_INS_DMULTU,
|
||||
MIPS_INS_DMULU,
|
||||
MIPS_INS_DOTP_S,
|
||||
MIPS_INS_DOTP_U,
|
||||
MIPS_INS_DPADD_S,
|
||||
MIPS_INS_DPADD_U,
|
||||
MIPS_INS_DPAQX_SA,
|
||||
MIPS_INS_DPAQX_S,
|
||||
MIPS_INS_DPAQ_SA,
|
||||
MIPS_INS_DPAQ_S,
|
||||
MIPS_INS_DPAU,
|
||||
MIPS_INS_DPAX,
|
||||
MIPS_INS_DPA,
|
||||
MIPS_INS_DPOP,
|
||||
MIPS_INS_DPSQX_SA,
|
||||
MIPS_INS_DPSQX_S,
|
||||
MIPS_INS_DPSQ_SA,
|
||||
MIPS_INS_DPSQ_S,
|
||||
MIPS_INS_DPSUB_S,
|
||||
MIPS_INS_DPSUB_U,
|
||||
MIPS_INS_DPSU,
|
||||
MIPS_INS_DPSX,
|
||||
MIPS_INS_DPS,
|
||||
MIPS_INS_DROTR,
|
||||
MIPS_INS_DROTR32,
|
||||
MIPS_INS_DROTRV,
|
||||
MIPS_INS_DSBH,
|
||||
MIPS_INS_DSHD,
|
||||
MIPS_INS_DSLL,
|
||||
MIPS_INS_DSLL32,
|
||||
MIPS_INS_DSLLV,
|
||||
MIPS_INS_DSRA,
|
||||
MIPS_INS_DSRA32,
|
||||
MIPS_INS_DSRAV,
|
||||
MIPS_INS_DSRL,
|
||||
MIPS_INS_DSRL32,
|
||||
MIPS_INS_DSRLV,
|
||||
MIPS_INS_DSUB,
|
||||
MIPS_INS_DSUBU,
|
||||
MIPS_INS_EHB,
|
||||
MIPS_INS_EI,
|
||||
MIPS_INS_ERET,
|
||||
MIPS_INS_EXT,
|
||||
MIPS_INS_EXTP,
|
||||
MIPS_INS_EXTPDP,
|
||||
MIPS_INS_EXTPDPV,
|
||||
MIPS_INS_EXTPV,
|
||||
MIPS_INS_EXTRV_RS,
|
||||
MIPS_INS_EXTRV_R,
|
||||
MIPS_INS_EXTRV_S,
|
||||
MIPS_INS_EXTRV,
|
||||
MIPS_INS_EXTR_RS,
|
||||
MIPS_INS_EXTR_R,
|
||||
MIPS_INS_EXTR_S,
|
||||
MIPS_INS_EXTR,
|
||||
MIPS_INS_EXTS,
|
||||
MIPS_INS_EXTS32,
|
||||
MIPS_INS_ABS,
|
||||
MIPS_INS_FADD,
|
||||
MIPS_INS_FCAF,
|
||||
MIPS_INS_FCEQ,
|
||||
MIPS_INS_FCLASS,
|
||||
MIPS_INS_FCLE,
|
||||
MIPS_INS_FCLT,
|
||||
MIPS_INS_FCNE,
|
||||
MIPS_INS_FCOR,
|
||||
MIPS_INS_FCUEQ,
|
||||
MIPS_INS_FCULE,
|
||||
MIPS_INS_FCULT,
|
||||
MIPS_INS_FCUNE,
|
||||
MIPS_INS_FCUN,
|
||||
MIPS_INS_FDIV,
|
||||
MIPS_INS_FEXDO,
|
||||
MIPS_INS_FEXP2,
|
||||
MIPS_INS_FEXUPL,
|
||||
MIPS_INS_FEXUPR,
|
||||
MIPS_INS_FFINT_S,
|
||||
MIPS_INS_FFINT_U,
|
||||
MIPS_INS_FFQL,
|
||||
MIPS_INS_FFQR,
|
||||
MIPS_INS_FILL,
|
||||
MIPS_INS_FLOG2,
|
||||
MIPS_INS_FLOOR,
|
||||
MIPS_INS_FMADD,
|
||||
MIPS_INS_FMAX_A,
|
||||
MIPS_INS_FMAX,
|
||||
MIPS_INS_FMIN_A,
|
||||
MIPS_INS_FMIN,
|
||||
MIPS_INS_MOV,
|
||||
MIPS_INS_FMSUB,
|
||||
MIPS_INS_FMUL,
|
||||
MIPS_INS_MUL,
|
||||
MIPS_INS_NEG,
|
||||
MIPS_INS_FRCP,
|
||||
MIPS_INS_FRINT,
|
||||
MIPS_INS_FRSQRT,
|
||||
MIPS_INS_FSAF,
|
||||
MIPS_INS_FSEQ,
|
||||
MIPS_INS_FSLE,
|
||||
MIPS_INS_FSLT,
|
||||
MIPS_INS_FSNE,
|
||||
MIPS_INS_FSOR,
|
||||
MIPS_INS_FSQRT,
|
||||
MIPS_INS_SQRT,
|
||||
MIPS_INS_FSUB,
|
||||
MIPS_INS_SUB,
|
||||
MIPS_INS_FSUEQ,
|
||||
MIPS_INS_FSULE,
|
||||
MIPS_INS_FSULT,
|
||||
MIPS_INS_FSUNE,
|
||||
MIPS_INS_FSUN,
|
||||
MIPS_INS_FTINT_S,
|
||||
MIPS_INS_FTINT_U,
|
||||
MIPS_INS_FTQ,
|
||||
MIPS_INS_FTRUNC_S,
|
||||
MIPS_INS_FTRUNC_U,
|
||||
MIPS_INS_HADD_S,
|
||||
MIPS_INS_HADD_U,
|
||||
MIPS_INS_HSUB_S,
|
||||
MIPS_INS_HSUB_U,
|
||||
MIPS_INS_ILVEV,
|
||||
MIPS_INS_ILVL,
|
||||
MIPS_INS_ILVOD,
|
||||
MIPS_INS_ILVR,
|
||||
MIPS_INS_INS,
|
||||
MIPS_INS_INSERT,
|
||||
MIPS_INS_INSV,
|
||||
MIPS_INS_INSVE,
|
||||
MIPS_INS_J,
|
||||
MIPS_INS_JAL,
|
||||
MIPS_INS_JALR,
|
||||
MIPS_INS_JALRS16,
|
||||
MIPS_INS_JALRS,
|
||||
MIPS_INS_JALS,
|
||||
MIPS_INS_JALX,
|
||||
MIPS_INS_JIALC,
|
||||
MIPS_INS_JIC,
|
||||
MIPS_INS_JR,
|
||||
MIPS_INS_JR16,
|
||||
MIPS_INS_JRADDIUSP,
|
||||
MIPS_INS_JRC,
|
||||
MIPS_INS_JALRC,
|
||||
MIPS_INS_LB,
|
||||
MIPS_INS_LBU16,
|
||||
MIPS_INS_LBUX,
|
||||
MIPS_INS_LBU,
|
||||
MIPS_INS_LD,
|
||||
MIPS_INS_LDC1,
|
||||
MIPS_INS_LDC2,
|
||||
MIPS_INS_LDC3,
|
||||
MIPS_INS_LDI,
|
||||
MIPS_INS_LDL,
|
||||
MIPS_INS_LDPC,
|
||||
MIPS_INS_LDR,
|
||||
MIPS_INS_LDXC1,
|
||||
MIPS_INS_LH,
|
||||
MIPS_INS_LHU16,
|
||||
MIPS_INS_LHX,
|
||||
MIPS_INS_LHU,
|
||||
MIPS_INS_LI16,
|
||||
MIPS_INS_LL,
|
||||
MIPS_INS_LLD,
|
||||
MIPS_INS_LSA,
|
||||
MIPS_INS_LUXC1,
|
||||
MIPS_INS_LUI,
|
||||
MIPS_INS_LW,
|
||||
MIPS_INS_LW16,
|
||||
MIPS_INS_LWC1,
|
||||
MIPS_INS_LWC2,
|
||||
MIPS_INS_LWC3,
|
||||
MIPS_INS_LWL,
|
||||
MIPS_INS_LWM16,
|
||||
MIPS_INS_LWM32,
|
||||
MIPS_INS_LWPC,
|
||||
MIPS_INS_LWP,
|
||||
MIPS_INS_LWR,
|
||||
MIPS_INS_LWUPC,
|
||||
MIPS_INS_LWU,
|
||||
MIPS_INS_LWX,
|
||||
MIPS_INS_LWXC1,
|
||||
MIPS_INS_LWXS,
|
||||
MIPS_INS_LI,
|
||||
MIPS_INS_MADD,
|
||||
MIPS_INS_MADDF,
|
||||
MIPS_INS_MADDR_Q,
|
||||
MIPS_INS_MADDU,
|
||||
MIPS_INS_MADDV,
|
||||
MIPS_INS_MADD_Q,
|
||||
MIPS_INS_MAQ_SA,
|
||||
MIPS_INS_MAQ_S,
|
||||
MIPS_INS_MAXA,
|
||||
MIPS_INS_MAXI_S,
|
||||
MIPS_INS_MAXI_U,
|
||||
MIPS_INS_MAX_A,
|
||||
MIPS_INS_MAX,
|
||||
MIPS_INS_MAX_S,
|
||||
MIPS_INS_MAX_U,
|
||||
MIPS_INS_MFC0,
|
||||
MIPS_INS_MFC1,
|
||||
MIPS_INS_MFC2,
|
||||
MIPS_INS_MFHC1,
|
||||
MIPS_INS_MFHI,
|
||||
MIPS_INS_MFLO,
|
||||
MIPS_INS_MINA,
|
||||
MIPS_INS_MINI_S,
|
||||
MIPS_INS_MINI_U,
|
||||
MIPS_INS_MIN_A,
|
||||
MIPS_INS_MIN,
|
||||
MIPS_INS_MIN_S,
|
||||
MIPS_INS_MIN_U,
|
||||
MIPS_INS_MOD,
|
||||
MIPS_INS_MODSUB,
|
||||
MIPS_INS_MODU,
|
||||
MIPS_INS_MOD_S,
|
||||
MIPS_INS_MOD_U,
|
||||
MIPS_INS_MOVE,
|
||||
MIPS_INS_MOVEP,
|
||||
MIPS_INS_MOVF,
|
||||
MIPS_INS_MOVN,
|
||||
MIPS_INS_MOVT,
|
||||
MIPS_INS_MOVZ,
|
||||
MIPS_INS_MSUB,
|
||||
MIPS_INS_MSUBF,
|
||||
MIPS_INS_MSUBR_Q,
|
||||
MIPS_INS_MSUBU,
|
||||
MIPS_INS_MSUBV,
|
||||
MIPS_INS_MSUB_Q,
|
||||
MIPS_INS_MTC0,
|
||||
MIPS_INS_MTC1,
|
||||
MIPS_INS_MTC2,
|
||||
MIPS_INS_MTHC1,
|
||||
MIPS_INS_MTHI,
|
||||
MIPS_INS_MTHLIP,
|
||||
MIPS_INS_MTLO,
|
||||
MIPS_INS_MTM0,
|
||||
MIPS_INS_MTM1,
|
||||
MIPS_INS_MTM2,
|
||||
MIPS_INS_MTP0,
|
||||
MIPS_INS_MTP1,
|
||||
MIPS_INS_MTP2,
|
||||
MIPS_INS_MUH,
|
||||
MIPS_INS_MUHU,
|
||||
MIPS_INS_MULEQ_S,
|
||||
MIPS_INS_MULEU_S,
|
||||
MIPS_INS_MULQ_RS,
|
||||
MIPS_INS_MULQ_S,
|
||||
MIPS_INS_MULR_Q,
|
||||
MIPS_INS_MULSAQ_S,
|
||||
MIPS_INS_MULSA,
|
||||
MIPS_INS_MULT,
|
||||
MIPS_INS_MULTU,
|
||||
MIPS_INS_MULU,
|
||||
MIPS_INS_MULV,
|
||||
MIPS_INS_MUL_Q,
|
||||
MIPS_INS_MUL_S,
|
||||
MIPS_INS_NLOC,
|
||||
MIPS_INS_NLZC,
|
||||
MIPS_INS_NMADD,
|
||||
MIPS_INS_NMSUB,
|
||||
MIPS_INS_NOR,
|
||||
MIPS_INS_NORI,
|
||||
MIPS_INS_NOT16,
|
||||
MIPS_INS_NOT,
|
||||
MIPS_INS_OR,
|
||||
MIPS_INS_OR16,
|
||||
MIPS_INS_ORI,
|
||||
MIPS_INS_PACKRL,
|
||||
MIPS_INS_PAUSE,
|
||||
MIPS_INS_PCKEV,
|
||||
MIPS_INS_PCKOD,
|
||||
MIPS_INS_PCNT,
|
||||
MIPS_INS_PICK,
|
||||
MIPS_INS_POP,
|
||||
MIPS_INS_PRECEQU,
|
||||
MIPS_INS_PRECEQ,
|
||||
MIPS_INS_PRECEU,
|
||||
MIPS_INS_PRECRQU_S,
|
||||
MIPS_INS_PRECRQ,
|
||||
MIPS_INS_PRECRQ_RS,
|
||||
MIPS_INS_PRECR,
|
||||
MIPS_INS_PRECR_SRA,
|
||||
MIPS_INS_PRECR_SRA_R,
|
||||
MIPS_INS_PREF,
|
||||
MIPS_INS_PREPEND,
|
||||
MIPS_INS_RADDU,
|
||||
MIPS_INS_RDDSP,
|
||||
MIPS_INS_RDHWR,
|
||||
MIPS_INS_REPLV,
|
||||
MIPS_INS_REPL,
|
||||
MIPS_INS_RINT,
|
||||
MIPS_INS_ROTR,
|
||||
MIPS_INS_ROTRV,
|
||||
MIPS_INS_ROUND,
|
||||
MIPS_INS_SAT_S,
|
||||
MIPS_INS_SAT_U,
|
||||
MIPS_INS_SB,
|
||||
MIPS_INS_SB16,
|
||||
MIPS_INS_SC,
|
||||
MIPS_INS_SCD,
|
||||
MIPS_INS_SD,
|
||||
MIPS_INS_SDBBP,
|
||||
MIPS_INS_SDBBP16,
|
||||
MIPS_INS_SDC1,
|
||||
MIPS_INS_SDC2,
|
||||
MIPS_INS_SDC3,
|
||||
MIPS_INS_SDL,
|
||||
MIPS_INS_SDR,
|
||||
MIPS_INS_SDXC1,
|
||||
MIPS_INS_SEB,
|
||||
MIPS_INS_SEH,
|
||||
MIPS_INS_SELEQZ,
|
||||
MIPS_INS_SELNEZ,
|
||||
MIPS_INS_SEL,
|
||||
MIPS_INS_SEQ,
|
||||
MIPS_INS_SEQI,
|
||||
MIPS_INS_SH,
|
||||
MIPS_INS_SH16,
|
||||
MIPS_INS_SHF,
|
||||
MIPS_INS_SHILO,
|
||||
MIPS_INS_SHILOV,
|
||||
MIPS_INS_SHLLV,
|
||||
MIPS_INS_SHLLV_S,
|
||||
MIPS_INS_SHLL,
|
||||
MIPS_INS_SHLL_S,
|
||||
MIPS_INS_SHRAV,
|
||||
MIPS_INS_SHRAV_R,
|
||||
MIPS_INS_SHRA,
|
||||
MIPS_INS_SHRA_R,
|
||||
MIPS_INS_SHRLV,
|
||||
MIPS_INS_SHRL,
|
||||
MIPS_INS_SLDI,
|
||||
MIPS_INS_SLD,
|
||||
MIPS_INS_SLL,
|
||||
MIPS_INS_SLL16,
|
||||
MIPS_INS_SLLI,
|
||||
MIPS_INS_SLLV,
|
||||
MIPS_INS_SLT,
|
||||
MIPS_INS_SLTI,
|
||||
MIPS_INS_SLTIU,
|
||||
MIPS_INS_SLTU,
|
||||
MIPS_INS_SNE,
|
||||
MIPS_INS_SNEI,
|
||||
MIPS_INS_SPLATI,
|
||||
MIPS_INS_SPLAT,
|
||||
MIPS_INS_SRA,
|
||||
MIPS_INS_SRAI,
|
||||
MIPS_INS_SRARI,
|
||||
MIPS_INS_SRAR,
|
||||
MIPS_INS_SRAV,
|
||||
MIPS_INS_SRL,
|
||||
MIPS_INS_SRL16,
|
||||
MIPS_INS_SRLI,
|
||||
MIPS_INS_SRLRI,
|
||||
MIPS_INS_SRLR,
|
||||
MIPS_INS_SRLV,
|
||||
MIPS_INS_SSNOP,
|
||||
MIPS_INS_ST,
|
||||
MIPS_INS_SUBQH,
|
||||
MIPS_INS_SUBQH_R,
|
||||
MIPS_INS_SUBQ,
|
||||
MIPS_INS_SUBQ_S,
|
||||
MIPS_INS_SUBSUS_U,
|
||||
MIPS_INS_SUBSUU_S,
|
||||
MIPS_INS_SUBS_S,
|
||||
MIPS_INS_SUBS_U,
|
||||
MIPS_INS_SUBU16,
|
||||
MIPS_INS_SUBUH,
|
||||
MIPS_INS_SUBUH_R,
|
||||
MIPS_INS_SUBU,
|
||||
MIPS_INS_SUBU_S,
|
||||
MIPS_INS_SUBVI,
|
||||
MIPS_INS_SUBV,
|
||||
MIPS_INS_SUXC1,
|
||||
MIPS_INS_SW,
|
||||
MIPS_INS_SW16,
|
||||
MIPS_INS_SWC1,
|
||||
MIPS_INS_SWC2,
|
||||
MIPS_INS_SWC3,
|
||||
MIPS_INS_SWL,
|
||||
MIPS_INS_SWM16,
|
||||
MIPS_INS_SWM32,
|
||||
MIPS_INS_SWP,
|
||||
MIPS_INS_SWR,
|
||||
MIPS_INS_SWXC1,
|
||||
MIPS_INS_SYNC,
|
||||
MIPS_INS_SYNCI,
|
||||
MIPS_INS_SYSCALL,
|
||||
MIPS_INS_TEQ,
|
||||
MIPS_INS_TEQI,
|
||||
MIPS_INS_TGE,
|
||||
MIPS_INS_TGEI,
|
||||
MIPS_INS_TGEIU,
|
||||
MIPS_INS_TGEU,
|
||||
MIPS_INS_TLBP,
|
||||
MIPS_INS_TLBR,
|
||||
MIPS_INS_TLBWI,
|
||||
MIPS_INS_TLBWR,
|
||||
MIPS_INS_TLT,
|
||||
MIPS_INS_TLTI,
|
||||
MIPS_INS_TLTIU,
|
||||
MIPS_INS_TLTU,
|
||||
MIPS_INS_TNE,
|
||||
MIPS_INS_TNEI,
|
||||
MIPS_INS_TRUNC,
|
||||
MIPS_INS_V3MULU,
|
||||
MIPS_INS_VMM0,
|
||||
MIPS_INS_VMULU,
|
||||
MIPS_INS_VSHF,
|
||||
MIPS_INS_WAIT,
|
||||
MIPS_INS_WRDSP,
|
||||
MIPS_INS_WSBH,
|
||||
MIPS_INS_XOR,
|
||||
MIPS_INS_XOR16,
|
||||
MIPS_INS_XORI,
|
||||
|
||||
//> some alias instructions
|
||||
MIPS_INS_NOP,
|
||||
MIPS_INS_NEGU,
|
||||
|
||||
//> special instructions
|
||||
MIPS_INS_JALR_HB, // jump and link with Hazard Barrier
|
||||
MIPS_INS_JR_HB, // jump register with Hazard Barrier
|
||||
|
||||
MIPS_INS_ENDING,
|
||||
} mips_insn;
|
||||
|
||||
/// Group of MIPS instructions
|
||||
typedef enum mips_insn_group {
|
||||
MIPS_GRP_INVALID = 0, ///< = CS_GRP_INVALID
|
||||
|
||||
// Generic groups
|
||||
// all jump instructions (conditional+direct+indirect jumps)
|
||||
MIPS_GRP_JUMP, ///< = CS_GRP_JUMP
|
||||
// all call instructions
|
||||
MIPS_GRP_CALL, ///< = CS_GRP_CALL
|
||||
// all return instructions
|
||||
MIPS_GRP_RET, ///< = CS_GRP_RET
|
||||
// all interrupt instructions (int+syscall)
|
||||
MIPS_GRP_INT, ///< = CS_GRP_INT
|
||||
// all interrupt return instructions
|
||||
MIPS_GRP_IRET, ///< = CS_GRP_IRET
|
||||
// all privileged instructions
|
||||
MIPS_GRP_PRIVILEGE, ///< = CS_GRP_PRIVILEGE
|
||||
// all relative branching instructions
|
||||
MIPS_GRP_BRANCH_RELATIVE, ///< = CS_GRP_BRANCH_RELATIVE
|
||||
|
||||
// Architecture-specific groups
|
||||
MIPS_GRP_BITCOUNT = 128,
|
||||
MIPS_GRP_DSP,
|
||||
MIPS_GRP_DSPR2,
|
||||
MIPS_GRP_FPIDX,
|
||||
MIPS_GRP_MSA,
|
||||
MIPS_GRP_MIPS32R2,
|
||||
MIPS_GRP_MIPS64,
|
||||
MIPS_GRP_MIPS64R2,
|
||||
MIPS_GRP_SEINREG,
|
||||
MIPS_GRP_STDENC,
|
||||
MIPS_GRP_SWAP,
|
||||
MIPS_GRP_MICROMIPS,
|
||||
MIPS_GRP_MIPS16MODE,
|
||||
MIPS_GRP_FP64BIT,
|
||||
MIPS_GRP_NONANSFPMATH,
|
||||
MIPS_GRP_NOTFP64BIT,
|
||||
MIPS_GRP_NOTINMICROMIPS,
|
||||
MIPS_GRP_NOTNACL,
|
||||
MIPS_GRP_NOTMIPS32R6,
|
||||
MIPS_GRP_NOTMIPS64R6,
|
||||
MIPS_GRP_CNMIPS,
|
||||
MIPS_GRP_MIPS32,
|
||||
MIPS_GRP_MIPS32R6,
|
||||
MIPS_GRP_MIPS64R6,
|
||||
MIPS_GRP_MIPS2,
|
||||
MIPS_GRP_MIPS3,
|
||||
MIPS_GRP_MIPS3_32,
|
||||
MIPS_GRP_MIPS3_32R2,
|
||||
MIPS_GRP_MIPS4_32,
|
||||
MIPS_GRP_MIPS4_32R2,
|
||||
MIPS_GRP_MIPS5_32R2,
|
||||
MIPS_GRP_GP32BIT,
|
||||
MIPS_GRP_GP64BIT,
|
||||
|
||||
MIPS_GRP_ENDING,
|
||||
} mips_insn_group;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,122 @@
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Axel Souchet & Nguyen Anh Quynh, 2014 */
|
||||
|
||||
#ifndef CAPSTONE_PLATFORM_H
|
||||
#define CAPSTONE_PLATFORM_H
|
||||
|
||||
|
||||
// handle C99 issue (for pre-2013 VisualStudio)
|
||||
#if !defined(__CYGWIN__) && !defined(__MINGW32__) && !defined(__MINGW64__) && (defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64))
|
||||
// MSVC
|
||||
|
||||
// stdbool.h
|
||||
#if (_MSC_VER < 1800) || defined(_KERNEL_MODE)
|
||||
// this system does not have stdbool.h
|
||||
#ifndef __cplusplus
|
||||
typedef unsigned char bool;
|
||||
#define false 0
|
||||
#define true 1
|
||||
#endif // __cplusplus
|
||||
|
||||
#else
|
||||
// VisualStudio 2013+ -> C99 is supported
|
||||
#include <stdbool.h>
|
||||
#endif // (_MSC_VER < 1800) || defined(_KERNEL_MODE)
|
||||
|
||||
#else
|
||||
// not MSVC -> C99 is supported
|
||||
#include <stdbool.h>
|
||||
#endif // !defined(__CYGWIN__) && !defined(__MINGW32__) && !defined(__MINGW64__) && (defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64))
|
||||
|
||||
|
||||
// handle inttypes.h / stdint.h compatibility
|
||||
#if defined(_WIN32_WCE) && (_WIN32_WCE < 0x800)
|
||||
#include "windowsce/stdint.h"
|
||||
#endif // defined(_WIN32_WCE) && (_WIN32_WCE < 0x800)
|
||||
|
||||
#if defined(CAPSTONE_HAS_OSXKERNEL) || (defined(_MSC_VER) && (_MSC_VER <= 1700 || defined(_KERNEL_MODE)))
|
||||
// this system does not have inttypes.h
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER <= 1600 || defined(_KERNEL_MODE))
|
||||
// this system does not have stdint.h
|
||||
typedef signed char int8_t;
|
||||
typedef signed short int16_t;
|
||||
typedef signed int int32_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef signed long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER <= 1600 || defined(_KERNEL_MODE))
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1600 || defined(_KERNEL_MODE))
|
||||
#define INT8_MIN (-127i8 - 1)
|
||||
#define INT16_MIN (-32767i16 - 1)
|
||||
#define INT32_MIN (-2147483647i32 - 1)
|
||||
#define INT64_MIN (-9223372036854775807i64 - 1)
|
||||
#define INT8_MAX 127i8
|
||||
#define INT16_MAX 32767i16
|
||||
#define INT32_MAX 2147483647i32
|
||||
#define INT64_MAX 9223372036854775807i64
|
||||
#define UINT8_MAX 0xffui8
|
||||
#define UINT16_MAX 0xffffui16
|
||||
#define UINT32_MAX 0xffffffffui32
|
||||
#define UINT64_MAX 0xffffffffffffffffui64
|
||||
#endif // defined(_MSC_VER) && (_MSC_VER < 1600 || defined(_KERNEL_MODE))
|
||||
|
||||
#ifdef CAPSTONE_HAS_OSXKERNEL
|
||||
// this system has stdint.h
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#define __PRI_8_LENGTH_MODIFIER__ "hh"
|
||||
#define __PRI_64_LENGTH_MODIFIER__ "ll"
|
||||
|
||||
#define PRId8 __PRI_8_LENGTH_MODIFIER__ "d"
|
||||
#define PRIi8 __PRI_8_LENGTH_MODIFIER__ "i"
|
||||
#define PRIo8 __PRI_8_LENGTH_MODIFIER__ "o"
|
||||
#define PRIu8 __PRI_8_LENGTH_MODIFIER__ "u"
|
||||
#define PRIx8 __PRI_8_LENGTH_MODIFIER__ "x"
|
||||
#define PRIX8 __PRI_8_LENGTH_MODIFIER__ "X"
|
||||
|
||||
#define PRId16 "hd"
|
||||
#define PRIi16 "hi"
|
||||
#define PRIo16 "ho"
|
||||
#define PRIu16 "hu"
|
||||
#define PRIx16 "hx"
|
||||
#define PRIX16 "hX"
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1700
|
||||
#define PRId32 "ld"
|
||||
#define PRIi32 "li"
|
||||
#define PRIo32 "lo"
|
||||
#define PRIu32 "lu"
|
||||
#define PRIx32 "lx"
|
||||
#define PRIX32 "lX"
|
||||
#else // OSX
|
||||
#define PRId32 "d"
|
||||
#define PRIi32 "i"
|
||||
#define PRIo32 "o"
|
||||
#define PRIu32 "u"
|
||||
#define PRIx32 "x"
|
||||
#define PRIX32 "X"
|
||||
#endif // defined(_MSC_VER) && _MSC_VER <= 1700
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1700
|
||||
// redefine functions from inttypes.h used in cstool
|
||||
#define strtoull _strtoui64
|
||||
#endif
|
||||
|
||||
#define PRId64 __PRI_64_LENGTH_MODIFIER__ "d"
|
||||
#define PRIi64 __PRI_64_LENGTH_MODIFIER__ "i"
|
||||
#define PRIo64 __PRI_64_LENGTH_MODIFIER__ "o"
|
||||
#define PRIu64 __PRI_64_LENGTH_MODIFIER__ "u"
|
||||
#define PRIx64 __PRI_64_LENGTH_MODIFIER__ "x"
|
||||
#define PRIX64 __PRI_64_LENGTH_MODIFIER__ "X"
|
||||
|
||||
#else
|
||||
// this system has inttypes.h by default
|
||||
#include <inttypes.h>
|
||||
#endif // defined(CAPSTONE_HAS_OSXKERNEL) || (defined(_MSC_VER) && (_MSC_VER <= 1700 || defined(_KERNEL_MODE)))
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,520 @@
|
||||
#ifndef CAPSTONE_SPARC_H
|
||||
#define CAPSTONE_SPARC_H
|
||||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2014-2015 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
// GCC SPARC toolchain has a default macro called "sparc" which breaks
|
||||
// compilation
|
||||
#undef sparc
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
/// Enums corresponding to Sparc condition codes, both icc's and fcc's.
|
||||
typedef enum sparc_cc {
|
||||
SPARC_CC_INVALID = 0, ///< invalid CC (default)
|
||||
// Integer condition codes
|
||||
SPARC_CC_ICC_A = 8+256, ///< Always
|
||||
SPARC_CC_ICC_N = 0+256, ///< Never
|
||||
SPARC_CC_ICC_NE = 9+256, ///< Not Equal
|
||||
SPARC_CC_ICC_E = 1+256, ///< Equal
|
||||
SPARC_CC_ICC_G = 10+256, ///< Greater
|
||||
SPARC_CC_ICC_LE = 2+256, ///< Less or Equal
|
||||
SPARC_CC_ICC_GE = 11+256, ///< Greater or Equal
|
||||
SPARC_CC_ICC_L = 3+256, ///< Less
|
||||
SPARC_CC_ICC_GU = 12+256, ///< Greater Unsigned
|
||||
SPARC_CC_ICC_LEU = 4+256, ///< Less or Equal Unsigned
|
||||
SPARC_CC_ICC_CC = 13+256, ///< Carry Clear/Great or Equal Unsigned
|
||||
SPARC_CC_ICC_CS = 5+256, ///< Carry Set/Less Unsigned
|
||||
SPARC_CC_ICC_POS = 14+256, ///< Positive
|
||||
SPARC_CC_ICC_NEG = 6+256, ///< Negative
|
||||
SPARC_CC_ICC_VC = 15+256, ///< Overflow Clear
|
||||
SPARC_CC_ICC_VS = 7+256, ///< Overflow Set
|
||||
|
||||
// Floating condition codes
|
||||
SPARC_CC_FCC_A = 8+16+256, ///< Always
|
||||
SPARC_CC_FCC_N = 0+16+256, ///< Never
|
||||
SPARC_CC_FCC_U = 7+16+256, ///< Unordered
|
||||
SPARC_CC_FCC_G = 6+16+256, ///< Greater
|
||||
SPARC_CC_FCC_UG = 5+16+256, ///< Unordered or Greater
|
||||
SPARC_CC_FCC_L = 4+16+256, ///< Less
|
||||
SPARC_CC_FCC_UL = 3+16+256, ///< Unordered or Less
|
||||
SPARC_CC_FCC_LG = 2+16+256, ///< Less or Greater
|
||||
SPARC_CC_FCC_NE = 1+16+256, ///< Not Equal
|
||||
SPARC_CC_FCC_E = 9+16+256, ///< Equal
|
||||
SPARC_CC_FCC_UE = 10+16+256, ///< Unordered or Equal
|
||||
SPARC_CC_FCC_GE = 11+16+256, ///< Greater or Equal
|
||||
SPARC_CC_FCC_UGE = 12+16+256, ///< Unordered or Greater or Equal
|
||||
SPARC_CC_FCC_LE = 13+16+256, ///< Less or Equal
|
||||
SPARC_CC_FCC_ULE = 14+16+256, ///< Unordered or Less or Equal
|
||||
SPARC_CC_FCC_O = 15+16+256, ///< Ordered
|
||||
} sparc_cc;
|
||||
|
||||
/// Branch hint
|
||||
typedef enum sparc_hint {
|
||||
SPARC_HINT_INVALID = 0, ///< no hint
|
||||
SPARC_HINT_A = 1 << 0, ///< annul delay slot instruction
|
||||
SPARC_HINT_PT = 1 << 1, ///< branch taken
|
||||
SPARC_HINT_PN = 1 << 2, ///< branch NOT taken
|
||||
} sparc_hint;
|
||||
|
||||
/// Operand type for instruction's operands
|
||||
typedef enum sparc_op_type {
|
||||
SPARC_OP_INVALID = 0, ///< = CS_OP_INVALID (Uninitialized).
|
||||
SPARC_OP_REG, ///< = CS_OP_REG (Register operand).
|
||||
SPARC_OP_IMM, ///< = CS_OP_IMM (Immediate operand).
|
||||
SPARC_OP_MEM, ///< = CS_OP_MEM (Memory operand).
|
||||
} sparc_op_type;
|
||||
|
||||
/// SPARC registers
|
||||
typedef enum sparc_reg {
|
||||
SPARC_REG_INVALID = 0,
|
||||
|
||||
SPARC_REG_F0,
|
||||
SPARC_REG_F1,
|
||||
SPARC_REG_F2,
|
||||
SPARC_REG_F3,
|
||||
SPARC_REG_F4,
|
||||
SPARC_REG_F5,
|
||||
SPARC_REG_F6,
|
||||
SPARC_REG_F7,
|
||||
SPARC_REG_F8,
|
||||
SPARC_REG_F9,
|
||||
SPARC_REG_F10,
|
||||
SPARC_REG_F11,
|
||||
SPARC_REG_F12,
|
||||
SPARC_REG_F13,
|
||||
SPARC_REG_F14,
|
||||
SPARC_REG_F15,
|
||||
SPARC_REG_F16,
|
||||
SPARC_REG_F17,
|
||||
SPARC_REG_F18,
|
||||
SPARC_REG_F19,
|
||||
SPARC_REG_F20,
|
||||
SPARC_REG_F21,
|
||||
SPARC_REG_F22,
|
||||
SPARC_REG_F23,
|
||||
SPARC_REG_F24,
|
||||
SPARC_REG_F25,
|
||||
SPARC_REG_F26,
|
||||
SPARC_REG_F27,
|
||||
SPARC_REG_F28,
|
||||
SPARC_REG_F29,
|
||||
SPARC_REG_F30,
|
||||
SPARC_REG_F31,
|
||||
SPARC_REG_F32,
|
||||
SPARC_REG_F34,
|
||||
SPARC_REG_F36,
|
||||
SPARC_REG_F38,
|
||||
SPARC_REG_F40,
|
||||
SPARC_REG_F42,
|
||||
SPARC_REG_F44,
|
||||
SPARC_REG_F46,
|
||||
SPARC_REG_F48,
|
||||
SPARC_REG_F50,
|
||||
SPARC_REG_F52,
|
||||
SPARC_REG_F54,
|
||||
SPARC_REG_F56,
|
||||
SPARC_REG_F58,
|
||||
SPARC_REG_F60,
|
||||
SPARC_REG_F62,
|
||||
SPARC_REG_FCC0, // Floating condition codes
|
||||
SPARC_REG_FCC1,
|
||||
SPARC_REG_FCC2,
|
||||
SPARC_REG_FCC3,
|
||||
SPARC_REG_FP,
|
||||
SPARC_REG_G0,
|
||||
SPARC_REG_G1,
|
||||
SPARC_REG_G2,
|
||||
SPARC_REG_G3,
|
||||
SPARC_REG_G4,
|
||||
SPARC_REG_G5,
|
||||
SPARC_REG_G6,
|
||||
SPARC_REG_G7,
|
||||
SPARC_REG_I0,
|
||||
SPARC_REG_I1,
|
||||
SPARC_REG_I2,
|
||||
SPARC_REG_I3,
|
||||
SPARC_REG_I4,
|
||||
SPARC_REG_I5,
|
||||
SPARC_REG_I7,
|
||||
SPARC_REG_ICC, // Integer condition codes
|
||||
SPARC_REG_L0,
|
||||
SPARC_REG_L1,
|
||||
SPARC_REG_L2,
|
||||
SPARC_REG_L3,
|
||||
SPARC_REG_L4,
|
||||
SPARC_REG_L5,
|
||||
SPARC_REG_L6,
|
||||
SPARC_REG_L7,
|
||||
SPARC_REG_O0,
|
||||
SPARC_REG_O1,
|
||||
SPARC_REG_O2,
|
||||
SPARC_REG_O3,
|
||||
SPARC_REG_O4,
|
||||
SPARC_REG_O5,
|
||||
SPARC_REG_O7,
|
||||
SPARC_REG_SP,
|
||||
SPARC_REG_Y,
|
||||
|
||||
// special register
|
||||
SPARC_REG_XCC,
|
||||
|
||||
SPARC_REG_ENDING, // <-- mark the end of the list of registers
|
||||
|
||||
// extras
|
||||
SPARC_REG_O6 = SPARC_REG_SP,
|
||||
SPARC_REG_I6 = SPARC_REG_FP,
|
||||
} sparc_reg;
|
||||
|
||||
/// Instruction's operand referring to memory
|
||||
/// This is associated with SPARC_OP_MEM operand type above
|
||||
typedef struct sparc_op_mem {
|
||||
uint8_t base; ///< base register, can be safely interpreted as
|
||||
///< a value of type `sparc_reg`, but it is only
|
||||
///< one byte wide
|
||||
uint8_t index; ///< index register, same conditions apply here
|
||||
int32_t disp; ///< displacement/offset value
|
||||
} sparc_op_mem;
|
||||
|
||||
/// Instruction operand
|
||||
typedef struct cs_sparc_op {
|
||||
sparc_op_type type; ///< operand type
|
||||
union {
|
||||
sparc_reg reg; ///< register value for REG operand
|
||||
int64_t imm; ///< immediate value for IMM operand
|
||||
sparc_op_mem mem; ///< base/disp value for MEM operand
|
||||
};
|
||||
} cs_sparc_op;
|
||||
|
||||
/// Instruction structure
|
||||
typedef struct cs_sparc {
|
||||
sparc_cc cc; ///< code condition for this insn
|
||||
sparc_hint hint; ///< branch hint: encoding as bitwise OR of sparc_hint.
|
||||
/// Number of operands of this instruction,
|
||||
/// or 0 when instruction has no operand.
|
||||
uint8_t op_count;
|
||||
cs_sparc_op operands[4]; ///< operands for this instruction.
|
||||
} cs_sparc;
|
||||
|
||||
/// SPARC instruction
|
||||
typedef enum sparc_insn {
|
||||
SPARC_INS_INVALID = 0,
|
||||
|
||||
SPARC_INS_ADDCC,
|
||||
SPARC_INS_ADDX,
|
||||
SPARC_INS_ADDXCC,
|
||||
SPARC_INS_ADDXC,
|
||||
SPARC_INS_ADDXCCC,
|
||||
SPARC_INS_ADD,
|
||||
SPARC_INS_ALIGNADDR,
|
||||
SPARC_INS_ALIGNADDRL,
|
||||
SPARC_INS_ANDCC,
|
||||
SPARC_INS_ANDNCC,
|
||||
SPARC_INS_ANDN,
|
||||
SPARC_INS_AND,
|
||||
SPARC_INS_ARRAY16,
|
||||
SPARC_INS_ARRAY32,
|
||||
SPARC_INS_ARRAY8,
|
||||
SPARC_INS_B,
|
||||
SPARC_INS_JMP,
|
||||
SPARC_INS_BMASK,
|
||||
SPARC_INS_FB,
|
||||
SPARC_INS_BRGEZ,
|
||||
SPARC_INS_BRGZ,
|
||||
SPARC_INS_BRLEZ,
|
||||
SPARC_INS_BRLZ,
|
||||
SPARC_INS_BRNZ,
|
||||
SPARC_INS_BRZ,
|
||||
SPARC_INS_BSHUFFLE,
|
||||
SPARC_INS_CALL,
|
||||
SPARC_INS_CASX,
|
||||
SPARC_INS_CAS,
|
||||
SPARC_INS_CMASK16,
|
||||
SPARC_INS_CMASK32,
|
||||
SPARC_INS_CMASK8,
|
||||
SPARC_INS_CMP,
|
||||
SPARC_INS_EDGE16,
|
||||
SPARC_INS_EDGE16L,
|
||||
SPARC_INS_EDGE16LN,
|
||||
SPARC_INS_EDGE16N,
|
||||
SPARC_INS_EDGE32,
|
||||
SPARC_INS_EDGE32L,
|
||||
SPARC_INS_EDGE32LN,
|
||||
SPARC_INS_EDGE32N,
|
||||
SPARC_INS_EDGE8,
|
||||
SPARC_INS_EDGE8L,
|
||||
SPARC_INS_EDGE8LN,
|
||||
SPARC_INS_EDGE8N,
|
||||
SPARC_INS_FABSD,
|
||||
SPARC_INS_FABSQ,
|
||||
SPARC_INS_FABSS,
|
||||
SPARC_INS_FADDD,
|
||||
SPARC_INS_FADDQ,
|
||||
SPARC_INS_FADDS,
|
||||
SPARC_INS_FALIGNDATA,
|
||||
SPARC_INS_FAND,
|
||||
SPARC_INS_FANDNOT1,
|
||||
SPARC_INS_FANDNOT1S,
|
||||
SPARC_INS_FANDNOT2,
|
||||
SPARC_INS_FANDNOT2S,
|
||||
SPARC_INS_FANDS,
|
||||
SPARC_INS_FCHKSM16,
|
||||
SPARC_INS_FCMPD,
|
||||
SPARC_INS_FCMPEQ16,
|
||||
SPARC_INS_FCMPEQ32,
|
||||
SPARC_INS_FCMPGT16,
|
||||
SPARC_INS_FCMPGT32,
|
||||
SPARC_INS_FCMPLE16,
|
||||
SPARC_INS_FCMPLE32,
|
||||
SPARC_INS_FCMPNE16,
|
||||
SPARC_INS_FCMPNE32,
|
||||
SPARC_INS_FCMPQ,
|
||||
SPARC_INS_FCMPS,
|
||||
SPARC_INS_FDIVD,
|
||||
SPARC_INS_FDIVQ,
|
||||
SPARC_INS_FDIVS,
|
||||
SPARC_INS_FDMULQ,
|
||||
SPARC_INS_FDTOI,
|
||||
SPARC_INS_FDTOQ,
|
||||
SPARC_INS_FDTOS,
|
||||
SPARC_INS_FDTOX,
|
||||
SPARC_INS_FEXPAND,
|
||||
SPARC_INS_FHADDD,
|
||||
SPARC_INS_FHADDS,
|
||||
SPARC_INS_FHSUBD,
|
||||
SPARC_INS_FHSUBS,
|
||||
SPARC_INS_FITOD,
|
||||
SPARC_INS_FITOQ,
|
||||
SPARC_INS_FITOS,
|
||||
SPARC_INS_FLCMPD,
|
||||
SPARC_INS_FLCMPS,
|
||||
SPARC_INS_FLUSHW,
|
||||
SPARC_INS_FMEAN16,
|
||||
SPARC_INS_FMOVD,
|
||||
SPARC_INS_FMOVQ,
|
||||
SPARC_INS_FMOVRDGEZ,
|
||||
SPARC_INS_FMOVRQGEZ,
|
||||
SPARC_INS_FMOVRSGEZ,
|
||||
SPARC_INS_FMOVRDGZ,
|
||||
SPARC_INS_FMOVRQGZ,
|
||||
SPARC_INS_FMOVRSGZ,
|
||||
SPARC_INS_FMOVRDLEZ,
|
||||
SPARC_INS_FMOVRQLEZ,
|
||||
SPARC_INS_FMOVRSLEZ,
|
||||
SPARC_INS_FMOVRDLZ,
|
||||
SPARC_INS_FMOVRQLZ,
|
||||
SPARC_INS_FMOVRSLZ,
|
||||
SPARC_INS_FMOVRDNZ,
|
||||
SPARC_INS_FMOVRQNZ,
|
||||
SPARC_INS_FMOVRSNZ,
|
||||
SPARC_INS_FMOVRDZ,
|
||||
SPARC_INS_FMOVRQZ,
|
||||
SPARC_INS_FMOVRSZ,
|
||||
SPARC_INS_FMOVS,
|
||||
SPARC_INS_FMUL8SUX16,
|
||||
SPARC_INS_FMUL8ULX16,
|
||||
SPARC_INS_FMUL8X16,
|
||||
SPARC_INS_FMUL8X16AL,
|
||||
SPARC_INS_FMUL8X16AU,
|
||||
SPARC_INS_FMULD,
|
||||
SPARC_INS_FMULD8SUX16,
|
||||
SPARC_INS_FMULD8ULX16,
|
||||
SPARC_INS_FMULQ,
|
||||
SPARC_INS_FMULS,
|
||||
SPARC_INS_FNADDD,
|
||||
SPARC_INS_FNADDS,
|
||||
SPARC_INS_FNAND,
|
||||
SPARC_INS_FNANDS,
|
||||
SPARC_INS_FNEGD,
|
||||
SPARC_INS_FNEGQ,
|
||||
SPARC_INS_FNEGS,
|
||||
SPARC_INS_FNHADDD,
|
||||
SPARC_INS_FNHADDS,
|
||||
SPARC_INS_FNOR,
|
||||
SPARC_INS_FNORS,
|
||||
SPARC_INS_FNOT1,
|
||||
SPARC_INS_FNOT1S,
|
||||
SPARC_INS_FNOT2,
|
||||
SPARC_INS_FNOT2S,
|
||||
SPARC_INS_FONE,
|
||||
SPARC_INS_FONES,
|
||||
SPARC_INS_FOR,
|
||||
SPARC_INS_FORNOT1,
|
||||
SPARC_INS_FORNOT1S,
|
||||
SPARC_INS_FORNOT2,
|
||||
SPARC_INS_FORNOT2S,
|
||||
SPARC_INS_FORS,
|
||||
SPARC_INS_FPACK16,
|
||||
SPARC_INS_FPACK32,
|
||||
SPARC_INS_FPACKFIX,
|
||||
SPARC_INS_FPADD16,
|
||||
SPARC_INS_FPADD16S,
|
||||
SPARC_INS_FPADD32,
|
||||
SPARC_INS_FPADD32S,
|
||||
SPARC_INS_FPADD64,
|
||||
SPARC_INS_FPMERGE,
|
||||
SPARC_INS_FPSUB16,
|
||||
SPARC_INS_FPSUB16S,
|
||||
SPARC_INS_FPSUB32,
|
||||
SPARC_INS_FPSUB32S,
|
||||
SPARC_INS_FQTOD,
|
||||
SPARC_INS_FQTOI,
|
||||
SPARC_INS_FQTOS,
|
||||
SPARC_INS_FQTOX,
|
||||
SPARC_INS_FSLAS16,
|
||||
SPARC_INS_FSLAS32,
|
||||
SPARC_INS_FSLL16,
|
||||
SPARC_INS_FSLL32,
|
||||
SPARC_INS_FSMULD,
|
||||
SPARC_INS_FSQRTD,
|
||||
SPARC_INS_FSQRTQ,
|
||||
SPARC_INS_FSQRTS,
|
||||
SPARC_INS_FSRA16,
|
||||
SPARC_INS_FSRA32,
|
||||
SPARC_INS_FSRC1,
|
||||
SPARC_INS_FSRC1S,
|
||||
SPARC_INS_FSRC2,
|
||||
SPARC_INS_FSRC2S,
|
||||
SPARC_INS_FSRL16,
|
||||
SPARC_INS_FSRL32,
|
||||
SPARC_INS_FSTOD,
|
||||
SPARC_INS_FSTOI,
|
||||
SPARC_INS_FSTOQ,
|
||||
SPARC_INS_FSTOX,
|
||||
SPARC_INS_FSUBD,
|
||||
SPARC_INS_FSUBQ,
|
||||
SPARC_INS_FSUBS,
|
||||
SPARC_INS_FXNOR,
|
||||
SPARC_INS_FXNORS,
|
||||
SPARC_INS_FXOR,
|
||||
SPARC_INS_FXORS,
|
||||
SPARC_INS_FXTOD,
|
||||
SPARC_INS_FXTOQ,
|
||||
SPARC_INS_FXTOS,
|
||||
SPARC_INS_FZERO,
|
||||
SPARC_INS_FZEROS,
|
||||
SPARC_INS_JMPL,
|
||||
SPARC_INS_LDD,
|
||||
SPARC_INS_LD,
|
||||
SPARC_INS_LDQ,
|
||||
SPARC_INS_LDSB,
|
||||
SPARC_INS_LDSH,
|
||||
SPARC_INS_LDSW,
|
||||
SPARC_INS_LDUB,
|
||||
SPARC_INS_LDUH,
|
||||
SPARC_INS_LDX,
|
||||
SPARC_INS_LZCNT,
|
||||
SPARC_INS_MEMBAR,
|
||||
SPARC_INS_MOVDTOX,
|
||||
SPARC_INS_MOV,
|
||||
SPARC_INS_MOVRGEZ,
|
||||
SPARC_INS_MOVRGZ,
|
||||
SPARC_INS_MOVRLEZ,
|
||||
SPARC_INS_MOVRLZ,
|
||||
SPARC_INS_MOVRNZ,
|
||||
SPARC_INS_MOVRZ,
|
||||
SPARC_INS_MOVSTOSW,
|
||||
SPARC_INS_MOVSTOUW,
|
||||
SPARC_INS_MULX,
|
||||
SPARC_INS_NOP,
|
||||
SPARC_INS_ORCC,
|
||||
SPARC_INS_ORNCC,
|
||||
SPARC_INS_ORN,
|
||||
SPARC_INS_OR,
|
||||
SPARC_INS_PDIST,
|
||||
SPARC_INS_PDISTN,
|
||||
SPARC_INS_POPC,
|
||||
SPARC_INS_RD,
|
||||
SPARC_INS_RESTORE,
|
||||
SPARC_INS_RETT,
|
||||
SPARC_INS_SAVE,
|
||||
SPARC_INS_SDIVCC,
|
||||
SPARC_INS_SDIVX,
|
||||
SPARC_INS_SDIV,
|
||||
SPARC_INS_SETHI,
|
||||
SPARC_INS_SHUTDOWN,
|
||||
SPARC_INS_SIAM,
|
||||
SPARC_INS_SLLX,
|
||||
SPARC_INS_SLL,
|
||||
SPARC_INS_SMULCC,
|
||||
SPARC_INS_SMUL,
|
||||
SPARC_INS_SRAX,
|
||||
SPARC_INS_SRA,
|
||||
SPARC_INS_SRLX,
|
||||
SPARC_INS_SRL,
|
||||
SPARC_INS_STBAR,
|
||||
SPARC_INS_STB,
|
||||
SPARC_INS_STD,
|
||||
SPARC_INS_ST,
|
||||
SPARC_INS_STH,
|
||||
SPARC_INS_STQ,
|
||||
SPARC_INS_STX,
|
||||
SPARC_INS_SUBCC,
|
||||
SPARC_INS_SUBX,
|
||||
SPARC_INS_SUBXCC,
|
||||
SPARC_INS_SUB,
|
||||
SPARC_INS_SWAP,
|
||||
SPARC_INS_TADDCCTV,
|
||||
SPARC_INS_TADDCC,
|
||||
SPARC_INS_T,
|
||||
SPARC_INS_TSUBCCTV,
|
||||
SPARC_INS_TSUBCC,
|
||||
SPARC_INS_UDIVCC,
|
||||
SPARC_INS_UDIVX,
|
||||
SPARC_INS_UDIV,
|
||||
SPARC_INS_UMULCC,
|
||||
SPARC_INS_UMULXHI,
|
||||
SPARC_INS_UMUL,
|
||||
SPARC_INS_UNIMP,
|
||||
SPARC_INS_FCMPED,
|
||||
SPARC_INS_FCMPEQ,
|
||||
SPARC_INS_FCMPES,
|
||||
SPARC_INS_WR,
|
||||
SPARC_INS_XMULX,
|
||||
SPARC_INS_XMULXHI,
|
||||
SPARC_INS_XNORCC,
|
||||
SPARC_INS_XNOR,
|
||||
SPARC_INS_XORCC,
|
||||
SPARC_INS_XOR,
|
||||
|
||||
// alias instructions
|
||||
SPARC_INS_RET,
|
||||
SPARC_INS_RETL,
|
||||
|
||||
SPARC_INS_ENDING, // <-- mark the end of the list of instructions
|
||||
} sparc_insn;
|
||||
|
||||
/// Group of SPARC instructions
|
||||
typedef enum sparc_insn_group {
|
||||
SPARC_GRP_INVALID = 0, ///< = CS_GRP_INVALID
|
||||
|
||||
// Generic groups
|
||||
// all jump instructions (conditional+direct+indirect jumps)
|
||||
SPARC_GRP_JUMP, ///< = CS_GRP_JUMP
|
||||
|
||||
// Architecture-specific groups
|
||||
SPARC_GRP_HARDQUAD = 128,
|
||||
SPARC_GRP_V9,
|
||||
SPARC_GRP_VIS,
|
||||
SPARC_GRP_VIS2,
|
||||
SPARC_GRP_VIS3,
|
||||
SPARC_GRP_32BIT,
|
||||
SPARC_GRP_64BIT,
|
||||
|
||||
SPARC_GRP_ENDING, // <-- mark the end of the list of groups
|
||||
} sparc_insn_group;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,830 @@
|
||||
#ifndef CAPSTONE_SYSTEMZ_H
|
||||
#define CAPSTONE_SYSTEMZ_H
|
||||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2014-2015 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
/// Enums corresponding to SystemZ condition codes
|
||||
typedef enum sysz_cc {
|
||||
SYSZ_CC_INVALID = 0, ///< invalid CC (default)
|
||||
|
||||
SYSZ_CC_O,
|
||||
SYSZ_CC_H,
|
||||
SYSZ_CC_NLE,
|
||||
SYSZ_CC_L,
|
||||
SYSZ_CC_NHE,
|
||||
SYSZ_CC_LH,
|
||||
SYSZ_CC_NE,
|
||||
SYSZ_CC_E,
|
||||
SYSZ_CC_NLH,
|
||||
SYSZ_CC_HE,
|
||||
SYSZ_CC_NL,
|
||||
SYSZ_CC_LE,
|
||||
SYSZ_CC_NH,
|
||||
SYSZ_CC_NO,
|
||||
} sysz_cc;
|
||||
|
||||
/// Operand type for instruction's operands
|
||||
typedef enum sysz_op_type {
|
||||
SYSZ_OP_INVALID = 0, ///< = CS_OP_INVALID (Uninitialized).
|
||||
SYSZ_OP_REG, ///< = CS_OP_REG (Register operand).
|
||||
SYSZ_OP_IMM, ///< = CS_OP_IMM (Immediate operand).
|
||||
SYSZ_OP_MEM, ///< = CS_OP_MEM (Memory operand).
|
||||
SYSZ_OP_ACREG = 64, ///< Access register operand.
|
||||
} sysz_op_type;
|
||||
|
||||
/// SystemZ registers
|
||||
typedef enum sysz_reg {
|
||||
SYSZ_REG_INVALID = 0,
|
||||
|
||||
SYSZ_REG_0,
|
||||
SYSZ_REG_1,
|
||||
SYSZ_REG_2,
|
||||
SYSZ_REG_3,
|
||||
SYSZ_REG_4,
|
||||
SYSZ_REG_5,
|
||||
SYSZ_REG_6,
|
||||
SYSZ_REG_7,
|
||||
SYSZ_REG_8,
|
||||
SYSZ_REG_9,
|
||||
SYSZ_REG_10,
|
||||
SYSZ_REG_11,
|
||||
SYSZ_REG_12,
|
||||
SYSZ_REG_13,
|
||||
SYSZ_REG_14,
|
||||
SYSZ_REG_15,
|
||||
SYSZ_REG_CC,
|
||||
SYSZ_REG_F0,
|
||||
SYSZ_REG_F1,
|
||||
SYSZ_REG_F2,
|
||||
SYSZ_REG_F3,
|
||||
SYSZ_REG_F4,
|
||||
SYSZ_REG_F5,
|
||||
SYSZ_REG_F6,
|
||||
SYSZ_REG_F7,
|
||||
SYSZ_REG_F8,
|
||||
SYSZ_REG_F9,
|
||||
SYSZ_REG_F10,
|
||||
SYSZ_REG_F11,
|
||||
SYSZ_REG_F12,
|
||||
SYSZ_REG_F13,
|
||||
SYSZ_REG_F14,
|
||||
SYSZ_REG_F15,
|
||||
|
||||
SYSZ_REG_R0L,
|
||||
|
||||
SYSZ_REG_ENDING,
|
||||
} sysz_reg;
|
||||
|
||||
/// Instruction's operand referring to memory
|
||||
/// This is associated with SYSZ_OP_MEM operand type above
|
||||
typedef struct sysz_op_mem {
|
||||
uint8_t base; ///< base register, can be safely interpreted as
|
||||
///< a value of type `sysz_reg`, but it is only
|
||||
///< one byte wide
|
||||
uint8_t index; ///< index register, same conditions apply here
|
||||
uint64_t length; ///< BDLAddr operand
|
||||
int64_t disp; ///< displacement/offset value
|
||||
} sysz_op_mem;
|
||||
|
||||
/// Instruction operand
|
||||
typedef struct cs_sysz_op {
|
||||
sysz_op_type type; ///< operand type
|
||||
union {
|
||||
sysz_reg reg; ///< register value for REG operand
|
||||
int64_t imm; ///< immediate value for IMM operand
|
||||
sysz_op_mem mem; ///< base/disp value for MEM operand
|
||||
};
|
||||
} cs_sysz_op;
|
||||
|
||||
// Instruction structure
|
||||
typedef struct cs_sysz {
|
||||
sysz_cc cc; ///< Code condition
|
||||
/// Number of operands of this instruction,
|
||||
/// or 0 when instruction has no operand.
|
||||
uint8_t op_count;
|
||||
cs_sysz_op operands[6]; ///< operands for this instruction.
|
||||
} cs_sysz;
|
||||
|
||||
/// SystemZ instruction
|
||||
typedef enum sysz_insn {
|
||||
SYSZ_INS_INVALID = 0,
|
||||
|
||||
SYSZ_INS_A,
|
||||
SYSZ_INS_ADB,
|
||||
SYSZ_INS_ADBR,
|
||||
SYSZ_INS_AEB,
|
||||
SYSZ_INS_AEBR,
|
||||
SYSZ_INS_AFI,
|
||||
SYSZ_INS_AG,
|
||||
SYSZ_INS_AGF,
|
||||
SYSZ_INS_AGFI,
|
||||
SYSZ_INS_AGFR,
|
||||
SYSZ_INS_AGHI,
|
||||
SYSZ_INS_AGHIK,
|
||||
SYSZ_INS_AGR,
|
||||
SYSZ_INS_AGRK,
|
||||
SYSZ_INS_AGSI,
|
||||
SYSZ_INS_AH,
|
||||
SYSZ_INS_AHI,
|
||||
SYSZ_INS_AHIK,
|
||||
SYSZ_INS_AHY,
|
||||
SYSZ_INS_AIH,
|
||||
SYSZ_INS_AL,
|
||||
SYSZ_INS_ALC,
|
||||
SYSZ_INS_ALCG,
|
||||
SYSZ_INS_ALCGR,
|
||||
SYSZ_INS_ALCR,
|
||||
SYSZ_INS_ALFI,
|
||||
SYSZ_INS_ALG,
|
||||
SYSZ_INS_ALGF,
|
||||
SYSZ_INS_ALGFI,
|
||||
SYSZ_INS_ALGFR,
|
||||
SYSZ_INS_ALGHSIK,
|
||||
SYSZ_INS_ALGR,
|
||||
SYSZ_INS_ALGRK,
|
||||
SYSZ_INS_ALHSIK,
|
||||
SYSZ_INS_ALR,
|
||||
SYSZ_INS_ALRK,
|
||||
SYSZ_INS_ALY,
|
||||
SYSZ_INS_AR,
|
||||
SYSZ_INS_ARK,
|
||||
SYSZ_INS_ASI,
|
||||
SYSZ_INS_AXBR,
|
||||
SYSZ_INS_AY,
|
||||
SYSZ_INS_BCR,
|
||||
SYSZ_INS_BRC,
|
||||
SYSZ_INS_BRCL,
|
||||
SYSZ_INS_CGIJ,
|
||||
SYSZ_INS_CGRJ,
|
||||
SYSZ_INS_CIJ,
|
||||
SYSZ_INS_CLGIJ,
|
||||
SYSZ_INS_CLGRJ,
|
||||
SYSZ_INS_CLIJ,
|
||||
SYSZ_INS_CLRJ,
|
||||
SYSZ_INS_CRJ,
|
||||
SYSZ_INS_BER,
|
||||
SYSZ_INS_JE,
|
||||
SYSZ_INS_JGE,
|
||||
SYSZ_INS_LOCE,
|
||||
SYSZ_INS_LOCGE,
|
||||
SYSZ_INS_LOCGRE,
|
||||
SYSZ_INS_LOCRE,
|
||||
SYSZ_INS_STOCE,
|
||||
SYSZ_INS_STOCGE,
|
||||
SYSZ_INS_BHR,
|
||||
SYSZ_INS_BHER,
|
||||
SYSZ_INS_JHE,
|
||||
SYSZ_INS_JGHE,
|
||||
SYSZ_INS_LOCHE,
|
||||
SYSZ_INS_LOCGHE,
|
||||
SYSZ_INS_LOCGRHE,
|
||||
SYSZ_INS_LOCRHE,
|
||||
SYSZ_INS_STOCHE,
|
||||
SYSZ_INS_STOCGHE,
|
||||
SYSZ_INS_JH,
|
||||
SYSZ_INS_JGH,
|
||||
SYSZ_INS_LOCH,
|
||||
SYSZ_INS_LOCGH,
|
||||
SYSZ_INS_LOCGRH,
|
||||
SYSZ_INS_LOCRH,
|
||||
SYSZ_INS_STOCH,
|
||||
SYSZ_INS_STOCGH,
|
||||
SYSZ_INS_CGIJNLH,
|
||||
SYSZ_INS_CGRJNLH,
|
||||
SYSZ_INS_CIJNLH,
|
||||
SYSZ_INS_CLGIJNLH,
|
||||
SYSZ_INS_CLGRJNLH,
|
||||
SYSZ_INS_CLIJNLH,
|
||||
SYSZ_INS_CLRJNLH,
|
||||
SYSZ_INS_CRJNLH,
|
||||
SYSZ_INS_CGIJE,
|
||||
SYSZ_INS_CGRJE,
|
||||
SYSZ_INS_CIJE,
|
||||
SYSZ_INS_CLGIJE,
|
||||
SYSZ_INS_CLGRJE,
|
||||
SYSZ_INS_CLIJE,
|
||||
SYSZ_INS_CLRJE,
|
||||
SYSZ_INS_CRJE,
|
||||
SYSZ_INS_CGIJNLE,
|
||||
SYSZ_INS_CGRJNLE,
|
||||
SYSZ_INS_CIJNLE,
|
||||
SYSZ_INS_CLGIJNLE,
|
||||
SYSZ_INS_CLGRJNLE,
|
||||
SYSZ_INS_CLIJNLE,
|
||||
SYSZ_INS_CLRJNLE,
|
||||
SYSZ_INS_CRJNLE,
|
||||
SYSZ_INS_CGIJH,
|
||||
SYSZ_INS_CGRJH,
|
||||
SYSZ_INS_CIJH,
|
||||
SYSZ_INS_CLGIJH,
|
||||
SYSZ_INS_CLGRJH,
|
||||
SYSZ_INS_CLIJH,
|
||||
SYSZ_INS_CLRJH,
|
||||
SYSZ_INS_CRJH,
|
||||
SYSZ_INS_CGIJNL,
|
||||
SYSZ_INS_CGRJNL,
|
||||
SYSZ_INS_CIJNL,
|
||||
SYSZ_INS_CLGIJNL,
|
||||
SYSZ_INS_CLGRJNL,
|
||||
SYSZ_INS_CLIJNL,
|
||||
SYSZ_INS_CLRJNL,
|
||||
SYSZ_INS_CRJNL,
|
||||
SYSZ_INS_CGIJHE,
|
||||
SYSZ_INS_CGRJHE,
|
||||
SYSZ_INS_CIJHE,
|
||||
SYSZ_INS_CLGIJHE,
|
||||
SYSZ_INS_CLGRJHE,
|
||||
SYSZ_INS_CLIJHE,
|
||||
SYSZ_INS_CLRJHE,
|
||||
SYSZ_INS_CRJHE,
|
||||
SYSZ_INS_CGIJNHE,
|
||||
SYSZ_INS_CGRJNHE,
|
||||
SYSZ_INS_CIJNHE,
|
||||
SYSZ_INS_CLGIJNHE,
|
||||
SYSZ_INS_CLGRJNHE,
|
||||
SYSZ_INS_CLIJNHE,
|
||||
SYSZ_INS_CLRJNHE,
|
||||
SYSZ_INS_CRJNHE,
|
||||
SYSZ_INS_CGIJL,
|
||||
SYSZ_INS_CGRJL,
|
||||
SYSZ_INS_CIJL,
|
||||
SYSZ_INS_CLGIJL,
|
||||
SYSZ_INS_CLGRJL,
|
||||
SYSZ_INS_CLIJL,
|
||||
SYSZ_INS_CLRJL,
|
||||
SYSZ_INS_CRJL,
|
||||
SYSZ_INS_CGIJNH,
|
||||
SYSZ_INS_CGRJNH,
|
||||
SYSZ_INS_CIJNH,
|
||||
SYSZ_INS_CLGIJNH,
|
||||
SYSZ_INS_CLGRJNH,
|
||||
SYSZ_INS_CLIJNH,
|
||||
SYSZ_INS_CLRJNH,
|
||||
SYSZ_INS_CRJNH,
|
||||
SYSZ_INS_CGIJLE,
|
||||
SYSZ_INS_CGRJLE,
|
||||
SYSZ_INS_CIJLE,
|
||||
SYSZ_INS_CLGIJLE,
|
||||
SYSZ_INS_CLGRJLE,
|
||||
SYSZ_INS_CLIJLE,
|
||||
SYSZ_INS_CLRJLE,
|
||||
SYSZ_INS_CRJLE,
|
||||
SYSZ_INS_CGIJNE,
|
||||
SYSZ_INS_CGRJNE,
|
||||
SYSZ_INS_CIJNE,
|
||||
SYSZ_INS_CLGIJNE,
|
||||
SYSZ_INS_CLGRJNE,
|
||||
SYSZ_INS_CLIJNE,
|
||||
SYSZ_INS_CLRJNE,
|
||||
SYSZ_INS_CRJNE,
|
||||
SYSZ_INS_CGIJLH,
|
||||
SYSZ_INS_CGRJLH,
|
||||
SYSZ_INS_CIJLH,
|
||||
SYSZ_INS_CLGIJLH,
|
||||
SYSZ_INS_CLGRJLH,
|
||||
SYSZ_INS_CLIJLH,
|
||||
SYSZ_INS_CLRJLH,
|
||||
SYSZ_INS_CRJLH,
|
||||
SYSZ_INS_BLR,
|
||||
SYSZ_INS_BLER,
|
||||
SYSZ_INS_JLE,
|
||||
SYSZ_INS_JGLE,
|
||||
SYSZ_INS_LOCLE,
|
||||
SYSZ_INS_LOCGLE,
|
||||
SYSZ_INS_LOCGRLE,
|
||||
SYSZ_INS_LOCRLE,
|
||||
SYSZ_INS_STOCLE,
|
||||
SYSZ_INS_STOCGLE,
|
||||
SYSZ_INS_BLHR,
|
||||
SYSZ_INS_JLH,
|
||||
SYSZ_INS_JGLH,
|
||||
SYSZ_INS_LOCLH,
|
||||
SYSZ_INS_LOCGLH,
|
||||
SYSZ_INS_LOCGRLH,
|
||||
SYSZ_INS_LOCRLH,
|
||||
SYSZ_INS_STOCLH,
|
||||
SYSZ_INS_STOCGLH,
|
||||
SYSZ_INS_JL,
|
||||
SYSZ_INS_JGL,
|
||||
SYSZ_INS_LOCL,
|
||||
SYSZ_INS_LOCGL,
|
||||
SYSZ_INS_LOCGRL,
|
||||
SYSZ_INS_LOCRL,
|
||||
SYSZ_INS_LOC,
|
||||
SYSZ_INS_LOCG,
|
||||
SYSZ_INS_LOCGR,
|
||||
SYSZ_INS_LOCR,
|
||||
SYSZ_INS_STOCL,
|
||||
SYSZ_INS_STOCGL,
|
||||
SYSZ_INS_BNER,
|
||||
SYSZ_INS_JNE,
|
||||
SYSZ_INS_JGNE,
|
||||
SYSZ_INS_LOCNE,
|
||||
SYSZ_INS_LOCGNE,
|
||||
SYSZ_INS_LOCGRNE,
|
||||
SYSZ_INS_LOCRNE,
|
||||
SYSZ_INS_STOCNE,
|
||||
SYSZ_INS_STOCGNE,
|
||||
SYSZ_INS_BNHR,
|
||||
SYSZ_INS_BNHER,
|
||||
SYSZ_INS_JNHE,
|
||||
SYSZ_INS_JGNHE,
|
||||
SYSZ_INS_LOCNHE,
|
||||
SYSZ_INS_LOCGNHE,
|
||||
SYSZ_INS_LOCGRNHE,
|
||||
SYSZ_INS_LOCRNHE,
|
||||
SYSZ_INS_STOCNHE,
|
||||
SYSZ_INS_STOCGNHE,
|
||||
SYSZ_INS_JNH,
|
||||
SYSZ_INS_JGNH,
|
||||
SYSZ_INS_LOCNH,
|
||||
SYSZ_INS_LOCGNH,
|
||||
SYSZ_INS_LOCGRNH,
|
||||
SYSZ_INS_LOCRNH,
|
||||
SYSZ_INS_STOCNH,
|
||||
SYSZ_INS_STOCGNH,
|
||||
SYSZ_INS_BNLR,
|
||||
SYSZ_INS_BNLER,
|
||||
SYSZ_INS_JNLE,
|
||||
SYSZ_INS_JGNLE,
|
||||
SYSZ_INS_LOCNLE,
|
||||
SYSZ_INS_LOCGNLE,
|
||||
SYSZ_INS_LOCGRNLE,
|
||||
SYSZ_INS_LOCRNLE,
|
||||
SYSZ_INS_STOCNLE,
|
||||
SYSZ_INS_STOCGNLE,
|
||||
SYSZ_INS_BNLHR,
|
||||
SYSZ_INS_JNLH,
|
||||
SYSZ_INS_JGNLH,
|
||||
SYSZ_INS_LOCNLH,
|
||||
SYSZ_INS_LOCGNLH,
|
||||
SYSZ_INS_LOCGRNLH,
|
||||
SYSZ_INS_LOCRNLH,
|
||||
SYSZ_INS_STOCNLH,
|
||||
SYSZ_INS_STOCGNLH,
|
||||
SYSZ_INS_JNL,
|
||||
SYSZ_INS_JGNL,
|
||||
SYSZ_INS_LOCNL,
|
||||
SYSZ_INS_LOCGNL,
|
||||
SYSZ_INS_LOCGRNL,
|
||||
SYSZ_INS_LOCRNL,
|
||||
SYSZ_INS_STOCNL,
|
||||
SYSZ_INS_STOCGNL,
|
||||
SYSZ_INS_BNOR,
|
||||
SYSZ_INS_JNO,
|
||||
SYSZ_INS_JGNO,
|
||||
SYSZ_INS_LOCNO,
|
||||
SYSZ_INS_LOCGNO,
|
||||
SYSZ_INS_LOCGRNO,
|
||||
SYSZ_INS_LOCRNO,
|
||||
SYSZ_INS_STOCNO,
|
||||
SYSZ_INS_STOCGNO,
|
||||
SYSZ_INS_BOR,
|
||||
SYSZ_INS_JO,
|
||||
SYSZ_INS_JGO,
|
||||
SYSZ_INS_LOCO,
|
||||
SYSZ_INS_LOCGO,
|
||||
SYSZ_INS_LOCGRO,
|
||||
SYSZ_INS_LOCRO,
|
||||
SYSZ_INS_STOCO,
|
||||
SYSZ_INS_STOCGO,
|
||||
SYSZ_INS_STOC,
|
||||
SYSZ_INS_STOCG,
|
||||
SYSZ_INS_BASR,
|
||||
SYSZ_INS_BR,
|
||||
SYSZ_INS_BRAS,
|
||||
SYSZ_INS_BRASL,
|
||||
SYSZ_INS_J,
|
||||
SYSZ_INS_JG,
|
||||
SYSZ_INS_BRCT,
|
||||
SYSZ_INS_BRCTG,
|
||||
SYSZ_INS_C,
|
||||
SYSZ_INS_CDB,
|
||||
SYSZ_INS_CDBR,
|
||||
SYSZ_INS_CDFBR,
|
||||
SYSZ_INS_CDGBR,
|
||||
SYSZ_INS_CDLFBR,
|
||||
SYSZ_INS_CDLGBR,
|
||||
SYSZ_INS_CEB,
|
||||
SYSZ_INS_CEBR,
|
||||
SYSZ_INS_CEFBR,
|
||||
SYSZ_INS_CEGBR,
|
||||
SYSZ_INS_CELFBR,
|
||||
SYSZ_INS_CELGBR,
|
||||
SYSZ_INS_CFDBR,
|
||||
SYSZ_INS_CFEBR,
|
||||
SYSZ_INS_CFI,
|
||||
SYSZ_INS_CFXBR,
|
||||
SYSZ_INS_CG,
|
||||
SYSZ_INS_CGDBR,
|
||||
SYSZ_INS_CGEBR,
|
||||
SYSZ_INS_CGF,
|
||||
SYSZ_INS_CGFI,
|
||||
SYSZ_INS_CGFR,
|
||||
SYSZ_INS_CGFRL,
|
||||
SYSZ_INS_CGH,
|
||||
SYSZ_INS_CGHI,
|
||||
SYSZ_INS_CGHRL,
|
||||
SYSZ_INS_CGHSI,
|
||||
SYSZ_INS_CGR,
|
||||
SYSZ_INS_CGRL,
|
||||
SYSZ_INS_CGXBR,
|
||||
SYSZ_INS_CH,
|
||||
SYSZ_INS_CHF,
|
||||
SYSZ_INS_CHHSI,
|
||||
SYSZ_INS_CHI,
|
||||
SYSZ_INS_CHRL,
|
||||
SYSZ_INS_CHSI,
|
||||
SYSZ_INS_CHY,
|
||||
SYSZ_INS_CIH,
|
||||
SYSZ_INS_CL,
|
||||
SYSZ_INS_CLC,
|
||||
SYSZ_INS_CLFDBR,
|
||||
SYSZ_INS_CLFEBR,
|
||||
SYSZ_INS_CLFHSI,
|
||||
SYSZ_INS_CLFI,
|
||||
SYSZ_INS_CLFXBR,
|
||||
SYSZ_INS_CLG,
|
||||
SYSZ_INS_CLGDBR,
|
||||
SYSZ_INS_CLGEBR,
|
||||
SYSZ_INS_CLGF,
|
||||
SYSZ_INS_CLGFI,
|
||||
SYSZ_INS_CLGFR,
|
||||
SYSZ_INS_CLGFRL,
|
||||
SYSZ_INS_CLGHRL,
|
||||
SYSZ_INS_CLGHSI,
|
||||
SYSZ_INS_CLGR,
|
||||
SYSZ_INS_CLGRL,
|
||||
SYSZ_INS_CLGXBR,
|
||||
SYSZ_INS_CLHF,
|
||||
SYSZ_INS_CLHHSI,
|
||||
SYSZ_INS_CLHRL,
|
||||
SYSZ_INS_CLI,
|
||||
SYSZ_INS_CLIH,
|
||||
SYSZ_INS_CLIY,
|
||||
SYSZ_INS_CLR,
|
||||
SYSZ_INS_CLRL,
|
||||
SYSZ_INS_CLST,
|
||||
SYSZ_INS_CLY,
|
||||
SYSZ_INS_CPSDR,
|
||||
SYSZ_INS_CR,
|
||||
SYSZ_INS_CRL,
|
||||
SYSZ_INS_CS,
|
||||
SYSZ_INS_CSG,
|
||||
SYSZ_INS_CSY,
|
||||
SYSZ_INS_CXBR,
|
||||
SYSZ_INS_CXFBR,
|
||||
SYSZ_INS_CXGBR,
|
||||
SYSZ_INS_CXLFBR,
|
||||
SYSZ_INS_CXLGBR,
|
||||
SYSZ_INS_CY,
|
||||
SYSZ_INS_DDB,
|
||||
SYSZ_INS_DDBR,
|
||||
SYSZ_INS_DEB,
|
||||
SYSZ_INS_DEBR,
|
||||
SYSZ_INS_DL,
|
||||
SYSZ_INS_DLG,
|
||||
SYSZ_INS_DLGR,
|
||||
SYSZ_INS_DLR,
|
||||
SYSZ_INS_DSG,
|
||||
SYSZ_INS_DSGF,
|
||||
SYSZ_INS_DSGFR,
|
||||
SYSZ_INS_DSGR,
|
||||
SYSZ_INS_DXBR,
|
||||
SYSZ_INS_EAR,
|
||||
SYSZ_INS_FIDBR,
|
||||
SYSZ_INS_FIDBRA,
|
||||
SYSZ_INS_FIEBR,
|
||||
SYSZ_INS_FIEBRA,
|
||||
SYSZ_INS_FIXBR,
|
||||
SYSZ_INS_FIXBRA,
|
||||
SYSZ_INS_FLOGR,
|
||||
SYSZ_INS_IC,
|
||||
SYSZ_INS_ICY,
|
||||
SYSZ_INS_IIHF,
|
||||
SYSZ_INS_IIHH,
|
||||
SYSZ_INS_IIHL,
|
||||
SYSZ_INS_IILF,
|
||||
SYSZ_INS_IILH,
|
||||
SYSZ_INS_IILL,
|
||||
SYSZ_INS_IPM,
|
||||
SYSZ_INS_L,
|
||||
SYSZ_INS_LA,
|
||||
SYSZ_INS_LAA,
|
||||
SYSZ_INS_LAAG,
|
||||
SYSZ_INS_LAAL,
|
||||
SYSZ_INS_LAALG,
|
||||
SYSZ_INS_LAN,
|
||||
SYSZ_INS_LANG,
|
||||
SYSZ_INS_LAO,
|
||||
SYSZ_INS_LAOG,
|
||||
SYSZ_INS_LARL,
|
||||
SYSZ_INS_LAX,
|
||||
SYSZ_INS_LAXG,
|
||||
SYSZ_INS_LAY,
|
||||
SYSZ_INS_LB,
|
||||
SYSZ_INS_LBH,
|
||||
SYSZ_INS_LBR,
|
||||
SYSZ_INS_LCDBR,
|
||||
SYSZ_INS_LCEBR,
|
||||
SYSZ_INS_LCGFR,
|
||||
SYSZ_INS_LCGR,
|
||||
SYSZ_INS_LCR,
|
||||
SYSZ_INS_LCXBR,
|
||||
SYSZ_INS_LD,
|
||||
SYSZ_INS_LDEB,
|
||||
SYSZ_INS_LDEBR,
|
||||
SYSZ_INS_LDGR,
|
||||
SYSZ_INS_LDR,
|
||||
SYSZ_INS_LDXBR,
|
||||
SYSZ_INS_LDXBRA,
|
||||
SYSZ_INS_LDY,
|
||||
SYSZ_INS_LE,
|
||||
SYSZ_INS_LEDBR,
|
||||
SYSZ_INS_LEDBRA,
|
||||
SYSZ_INS_LER,
|
||||
SYSZ_INS_LEXBR,
|
||||
SYSZ_INS_LEXBRA,
|
||||
SYSZ_INS_LEY,
|
||||
SYSZ_INS_LFH,
|
||||
SYSZ_INS_LG,
|
||||
SYSZ_INS_LGB,
|
||||
SYSZ_INS_LGBR,
|
||||
SYSZ_INS_LGDR,
|
||||
SYSZ_INS_LGF,
|
||||
SYSZ_INS_LGFI,
|
||||
SYSZ_INS_LGFR,
|
||||
SYSZ_INS_LGFRL,
|
||||
SYSZ_INS_LGH,
|
||||
SYSZ_INS_LGHI,
|
||||
SYSZ_INS_LGHR,
|
||||
SYSZ_INS_LGHRL,
|
||||
SYSZ_INS_LGR,
|
||||
SYSZ_INS_LGRL,
|
||||
SYSZ_INS_LH,
|
||||
SYSZ_INS_LHH,
|
||||
SYSZ_INS_LHI,
|
||||
SYSZ_INS_LHR,
|
||||
SYSZ_INS_LHRL,
|
||||
SYSZ_INS_LHY,
|
||||
SYSZ_INS_LLC,
|
||||
SYSZ_INS_LLCH,
|
||||
SYSZ_INS_LLCR,
|
||||
SYSZ_INS_LLGC,
|
||||
SYSZ_INS_LLGCR,
|
||||
SYSZ_INS_LLGF,
|
||||
SYSZ_INS_LLGFR,
|
||||
SYSZ_INS_LLGFRL,
|
||||
SYSZ_INS_LLGH,
|
||||
SYSZ_INS_LLGHR,
|
||||
SYSZ_INS_LLGHRL,
|
||||
SYSZ_INS_LLH,
|
||||
SYSZ_INS_LLHH,
|
||||
SYSZ_INS_LLHR,
|
||||
SYSZ_INS_LLHRL,
|
||||
SYSZ_INS_LLIHF,
|
||||
SYSZ_INS_LLIHH,
|
||||
SYSZ_INS_LLIHL,
|
||||
SYSZ_INS_LLILF,
|
||||
SYSZ_INS_LLILH,
|
||||
SYSZ_INS_LLILL,
|
||||
SYSZ_INS_LMG,
|
||||
SYSZ_INS_LNDBR,
|
||||
SYSZ_INS_LNEBR,
|
||||
SYSZ_INS_LNGFR,
|
||||
SYSZ_INS_LNGR,
|
||||
SYSZ_INS_LNR,
|
||||
SYSZ_INS_LNXBR,
|
||||
SYSZ_INS_LPDBR,
|
||||
SYSZ_INS_LPEBR,
|
||||
SYSZ_INS_LPGFR,
|
||||
SYSZ_INS_LPGR,
|
||||
SYSZ_INS_LPR,
|
||||
SYSZ_INS_LPXBR,
|
||||
SYSZ_INS_LR,
|
||||
SYSZ_INS_LRL,
|
||||
SYSZ_INS_LRV,
|
||||
SYSZ_INS_LRVG,
|
||||
SYSZ_INS_LRVGR,
|
||||
SYSZ_INS_LRVR,
|
||||
SYSZ_INS_LT,
|
||||
SYSZ_INS_LTDBR,
|
||||
SYSZ_INS_LTEBR,
|
||||
SYSZ_INS_LTG,
|
||||
SYSZ_INS_LTGF,
|
||||
SYSZ_INS_LTGFR,
|
||||
SYSZ_INS_LTGR,
|
||||
SYSZ_INS_LTR,
|
||||
SYSZ_INS_LTXBR,
|
||||
SYSZ_INS_LXDB,
|
||||
SYSZ_INS_LXDBR,
|
||||
SYSZ_INS_LXEB,
|
||||
SYSZ_INS_LXEBR,
|
||||
SYSZ_INS_LXR,
|
||||
SYSZ_INS_LY,
|
||||
SYSZ_INS_LZDR,
|
||||
SYSZ_INS_LZER,
|
||||
SYSZ_INS_LZXR,
|
||||
SYSZ_INS_MADB,
|
||||
SYSZ_INS_MADBR,
|
||||
SYSZ_INS_MAEB,
|
||||
SYSZ_INS_MAEBR,
|
||||
SYSZ_INS_MDB,
|
||||
SYSZ_INS_MDBR,
|
||||
SYSZ_INS_MDEB,
|
||||
SYSZ_INS_MDEBR,
|
||||
SYSZ_INS_MEEB,
|
||||
SYSZ_INS_MEEBR,
|
||||
SYSZ_INS_MGHI,
|
||||
SYSZ_INS_MH,
|
||||
SYSZ_INS_MHI,
|
||||
SYSZ_INS_MHY,
|
||||
SYSZ_INS_MLG,
|
||||
SYSZ_INS_MLGR,
|
||||
SYSZ_INS_MS,
|
||||
SYSZ_INS_MSDB,
|
||||
SYSZ_INS_MSDBR,
|
||||
SYSZ_INS_MSEB,
|
||||
SYSZ_INS_MSEBR,
|
||||
SYSZ_INS_MSFI,
|
||||
SYSZ_INS_MSG,
|
||||
SYSZ_INS_MSGF,
|
||||
SYSZ_INS_MSGFI,
|
||||
SYSZ_INS_MSGFR,
|
||||
SYSZ_INS_MSGR,
|
||||
SYSZ_INS_MSR,
|
||||
SYSZ_INS_MSY,
|
||||
SYSZ_INS_MVC,
|
||||
SYSZ_INS_MVGHI,
|
||||
SYSZ_INS_MVHHI,
|
||||
SYSZ_INS_MVHI,
|
||||
SYSZ_INS_MVI,
|
||||
SYSZ_INS_MVIY,
|
||||
SYSZ_INS_MVST,
|
||||
SYSZ_INS_MXBR,
|
||||
SYSZ_INS_MXDB,
|
||||
SYSZ_INS_MXDBR,
|
||||
SYSZ_INS_N,
|
||||
SYSZ_INS_NC,
|
||||
SYSZ_INS_NG,
|
||||
SYSZ_INS_NGR,
|
||||
SYSZ_INS_NGRK,
|
||||
SYSZ_INS_NI,
|
||||
SYSZ_INS_NIHF,
|
||||
SYSZ_INS_NIHH,
|
||||
SYSZ_INS_NIHL,
|
||||
SYSZ_INS_NILF,
|
||||
SYSZ_INS_NILH,
|
||||
SYSZ_INS_NILL,
|
||||
SYSZ_INS_NIY,
|
||||
SYSZ_INS_NR,
|
||||
SYSZ_INS_NRK,
|
||||
SYSZ_INS_NY,
|
||||
SYSZ_INS_O,
|
||||
SYSZ_INS_OC,
|
||||
SYSZ_INS_OG,
|
||||
SYSZ_INS_OGR,
|
||||
SYSZ_INS_OGRK,
|
||||
SYSZ_INS_OI,
|
||||
SYSZ_INS_OIHF,
|
||||
SYSZ_INS_OIHH,
|
||||
SYSZ_INS_OIHL,
|
||||
SYSZ_INS_OILF,
|
||||
SYSZ_INS_OILH,
|
||||
SYSZ_INS_OILL,
|
||||
SYSZ_INS_OIY,
|
||||
SYSZ_INS_OR,
|
||||
SYSZ_INS_ORK,
|
||||
SYSZ_INS_OY,
|
||||
SYSZ_INS_PFD,
|
||||
SYSZ_INS_PFDRL,
|
||||
SYSZ_INS_RISBG,
|
||||
SYSZ_INS_RISBHG,
|
||||
SYSZ_INS_RISBLG,
|
||||
SYSZ_INS_RLL,
|
||||
SYSZ_INS_RLLG,
|
||||
SYSZ_INS_RNSBG,
|
||||
SYSZ_INS_ROSBG,
|
||||
SYSZ_INS_RXSBG,
|
||||
SYSZ_INS_S,
|
||||
SYSZ_INS_SDB,
|
||||
SYSZ_INS_SDBR,
|
||||
SYSZ_INS_SEB,
|
||||
SYSZ_INS_SEBR,
|
||||
SYSZ_INS_SG,
|
||||
SYSZ_INS_SGF,
|
||||
SYSZ_INS_SGFR,
|
||||
SYSZ_INS_SGR,
|
||||
SYSZ_INS_SGRK,
|
||||
SYSZ_INS_SH,
|
||||
SYSZ_INS_SHY,
|
||||
SYSZ_INS_SL,
|
||||
SYSZ_INS_SLB,
|
||||
SYSZ_INS_SLBG,
|
||||
SYSZ_INS_SLBR,
|
||||
SYSZ_INS_SLFI,
|
||||
SYSZ_INS_SLG,
|
||||
SYSZ_INS_SLBGR,
|
||||
SYSZ_INS_SLGF,
|
||||
SYSZ_INS_SLGFI,
|
||||
SYSZ_INS_SLGFR,
|
||||
SYSZ_INS_SLGR,
|
||||
SYSZ_INS_SLGRK,
|
||||
SYSZ_INS_SLL,
|
||||
SYSZ_INS_SLLG,
|
||||
SYSZ_INS_SLLK,
|
||||
SYSZ_INS_SLR,
|
||||
SYSZ_INS_SLRK,
|
||||
SYSZ_INS_SLY,
|
||||
SYSZ_INS_SQDB,
|
||||
SYSZ_INS_SQDBR,
|
||||
SYSZ_INS_SQEB,
|
||||
SYSZ_INS_SQEBR,
|
||||
SYSZ_INS_SQXBR,
|
||||
SYSZ_INS_SR,
|
||||
SYSZ_INS_SRA,
|
||||
SYSZ_INS_SRAG,
|
||||
SYSZ_INS_SRAK,
|
||||
SYSZ_INS_SRK,
|
||||
SYSZ_INS_SRL,
|
||||
SYSZ_INS_SRLG,
|
||||
SYSZ_INS_SRLK,
|
||||
SYSZ_INS_SRST,
|
||||
SYSZ_INS_ST,
|
||||
SYSZ_INS_STC,
|
||||
SYSZ_INS_STCH,
|
||||
SYSZ_INS_STCY,
|
||||
SYSZ_INS_STD,
|
||||
SYSZ_INS_STDY,
|
||||
SYSZ_INS_STE,
|
||||
SYSZ_INS_STEY,
|
||||
SYSZ_INS_STFH,
|
||||
SYSZ_INS_STG,
|
||||
SYSZ_INS_STGRL,
|
||||
SYSZ_INS_STH,
|
||||
SYSZ_INS_STHH,
|
||||
SYSZ_INS_STHRL,
|
||||
SYSZ_INS_STHY,
|
||||
SYSZ_INS_STMG,
|
||||
SYSZ_INS_STRL,
|
||||
SYSZ_INS_STRV,
|
||||
SYSZ_INS_STRVG,
|
||||
SYSZ_INS_STY,
|
||||
SYSZ_INS_SXBR,
|
||||
SYSZ_INS_SY,
|
||||
SYSZ_INS_TM,
|
||||
SYSZ_INS_TMHH,
|
||||
SYSZ_INS_TMHL,
|
||||
SYSZ_INS_TMLH,
|
||||
SYSZ_INS_TMLL,
|
||||
SYSZ_INS_TMY,
|
||||
SYSZ_INS_X,
|
||||
SYSZ_INS_XC,
|
||||
SYSZ_INS_XG,
|
||||
SYSZ_INS_XGR,
|
||||
SYSZ_INS_XGRK,
|
||||
SYSZ_INS_XI,
|
||||
SYSZ_INS_XIHF,
|
||||
SYSZ_INS_XILF,
|
||||
SYSZ_INS_XIY,
|
||||
SYSZ_INS_XR,
|
||||
SYSZ_INS_XRK,
|
||||
SYSZ_INS_XY,
|
||||
|
||||
SYSZ_INS_ENDING, // <-- mark the end of the list of instructions
|
||||
} sysz_insn;
|
||||
|
||||
/// Group of SystemZ instructions
|
||||
typedef enum sysz_insn_group {
|
||||
SYSZ_GRP_INVALID = 0, ///< = CS_GRP_INVALID
|
||||
|
||||
// Generic groups
|
||||
// all jump instructions (conditional+direct+indirect jumps)
|
||||
SYSZ_GRP_JUMP, ///< = CS_GRP_JUMP
|
||||
|
||||
// Architecture-specific groups
|
||||
SYSZ_GRP_DISTINCTOPS = 128,
|
||||
SYSZ_GRP_FPEXTENSION,
|
||||
SYSZ_GRP_HIGHWORD,
|
||||
SYSZ_GRP_INTERLOCKEDACCESS1,
|
||||
SYSZ_GRP_LOADSTOREONCOND,
|
||||
|
||||
SYSZ_GRP_ENDING, // <-- mark the end of the list of groups
|
||||
} sysz_insn_group;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,359 @@
|
||||
/* Capstone Disassembly Engine */
|
||||
/* TMS320C64x Backend by Fotis Loukos <me@fotisl.com> 2016 */
|
||||
|
||||
#ifndef CAPSTONE_TMS320C64X_H
|
||||
#define CAPSTONE_TMS320C64X_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
typedef enum tms320c64x_op_type {
|
||||
TMS320C64X_OP_INVALID = 0, ///< = CS_OP_INVALID (Uninitialized).
|
||||
TMS320C64X_OP_REG, ///< = CS_OP_REG (Register operand).
|
||||
TMS320C64X_OP_IMM, ///< = CS_OP_IMM (Immediate operand).
|
||||
TMS320C64X_OP_MEM, ///< = CS_OP_MEM (Memory operand).
|
||||
TMS320C64X_OP_REGPAIR = 64, ///< Register pair for double word ops
|
||||
} tms320c64x_op_type;
|
||||
|
||||
typedef enum tms320c64x_mem_disp {
|
||||
TMS320C64X_MEM_DISP_INVALID = 0,
|
||||
TMS320C64X_MEM_DISP_CONSTANT,
|
||||
TMS320C64X_MEM_DISP_REGISTER,
|
||||
} tms320c64x_mem_disp;
|
||||
|
||||
typedef enum tms320c64x_mem_dir {
|
||||
TMS320C64X_MEM_DIR_INVALID = 0,
|
||||
TMS320C64X_MEM_DIR_FW,
|
||||
TMS320C64X_MEM_DIR_BW,
|
||||
} tms320c64x_mem_dir;
|
||||
|
||||
typedef enum tms320c64x_mem_mod {
|
||||
TMS320C64X_MEM_MOD_INVALID = 0,
|
||||
TMS320C64X_MEM_MOD_NO,
|
||||
TMS320C64X_MEM_MOD_PRE,
|
||||
TMS320C64X_MEM_MOD_POST,
|
||||
} tms320c64x_mem_mod;
|
||||
|
||||
typedef struct tms320c64x_op_mem {
|
||||
unsigned int base; ///< base register
|
||||
unsigned int disp; ///< displacement/offset value
|
||||
unsigned int unit; ///< unit of base and offset register
|
||||
unsigned int scaled; ///< offset scaled
|
||||
unsigned int disptype; ///< displacement type
|
||||
unsigned int direction; ///< direction
|
||||
unsigned int modify; ///< modification
|
||||
} tms320c64x_op_mem;
|
||||
|
||||
typedef struct cs_tms320c64x_op {
|
||||
tms320c64x_op_type type; ///< operand type
|
||||
union {
|
||||
unsigned int reg; ///< register value for REG operand or first register for REGPAIR operand
|
||||
int32_t imm; ///< immediate value for IMM operand
|
||||
tms320c64x_op_mem mem; ///< base/disp value for MEM operand
|
||||
};
|
||||
} cs_tms320c64x_op;
|
||||
|
||||
typedef struct cs_tms320c64x {
|
||||
uint8_t op_count;
|
||||
cs_tms320c64x_op operands[8]; ///< operands for this instruction.
|
||||
struct {
|
||||
unsigned int reg;
|
||||
unsigned int zero;
|
||||
} condition;
|
||||
struct {
|
||||
unsigned int unit;
|
||||
unsigned int side;
|
||||
unsigned int crosspath;
|
||||
} funit;
|
||||
unsigned int parallel;
|
||||
} cs_tms320c64x;
|
||||
|
||||
typedef enum tms320c64x_reg {
|
||||
TMS320C64X_REG_INVALID = 0,
|
||||
|
||||
TMS320C64X_REG_AMR,
|
||||
TMS320C64X_REG_CSR,
|
||||
TMS320C64X_REG_DIER,
|
||||
TMS320C64X_REG_DNUM,
|
||||
TMS320C64X_REG_ECR,
|
||||
TMS320C64X_REG_GFPGFR,
|
||||
TMS320C64X_REG_GPLYA,
|
||||
TMS320C64X_REG_GPLYB,
|
||||
TMS320C64X_REG_ICR,
|
||||
TMS320C64X_REG_IER,
|
||||
TMS320C64X_REG_IERR,
|
||||
TMS320C64X_REG_ILC,
|
||||
TMS320C64X_REG_IRP,
|
||||
TMS320C64X_REG_ISR,
|
||||
TMS320C64X_REG_ISTP,
|
||||
TMS320C64X_REG_ITSR,
|
||||
TMS320C64X_REG_NRP,
|
||||
TMS320C64X_REG_NTSR,
|
||||
TMS320C64X_REG_REP,
|
||||
TMS320C64X_REG_RILC,
|
||||
TMS320C64X_REG_SSR,
|
||||
TMS320C64X_REG_TSCH,
|
||||
TMS320C64X_REG_TSCL,
|
||||
TMS320C64X_REG_TSR,
|
||||
TMS320C64X_REG_A0,
|
||||
TMS320C64X_REG_A1,
|
||||
TMS320C64X_REG_A2,
|
||||
TMS320C64X_REG_A3,
|
||||
TMS320C64X_REG_A4,
|
||||
TMS320C64X_REG_A5,
|
||||
TMS320C64X_REG_A6,
|
||||
TMS320C64X_REG_A7,
|
||||
TMS320C64X_REG_A8,
|
||||
TMS320C64X_REG_A9,
|
||||
TMS320C64X_REG_A10,
|
||||
TMS320C64X_REG_A11,
|
||||
TMS320C64X_REG_A12,
|
||||
TMS320C64X_REG_A13,
|
||||
TMS320C64X_REG_A14,
|
||||
TMS320C64X_REG_A15,
|
||||
TMS320C64X_REG_A16,
|
||||
TMS320C64X_REG_A17,
|
||||
TMS320C64X_REG_A18,
|
||||
TMS320C64X_REG_A19,
|
||||
TMS320C64X_REG_A20,
|
||||
TMS320C64X_REG_A21,
|
||||
TMS320C64X_REG_A22,
|
||||
TMS320C64X_REG_A23,
|
||||
TMS320C64X_REG_A24,
|
||||
TMS320C64X_REG_A25,
|
||||
TMS320C64X_REG_A26,
|
||||
TMS320C64X_REG_A27,
|
||||
TMS320C64X_REG_A28,
|
||||
TMS320C64X_REG_A29,
|
||||
TMS320C64X_REG_A30,
|
||||
TMS320C64X_REG_A31,
|
||||
TMS320C64X_REG_B0,
|
||||
TMS320C64X_REG_B1,
|
||||
TMS320C64X_REG_B2,
|
||||
TMS320C64X_REG_B3,
|
||||
TMS320C64X_REG_B4,
|
||||
TMS320C64X_REG_B5,
|
||||
TMS320C64X_REG_B6,
|
||||
TMS320C64X_REG_B7,
|
||||
TMS320C64X_REG_B8,
|
||||
TMS320C64X_REG_B9,
|
||||
TMS320C64X_REG_B10,
|
||||
TMS320C64X_REG_B11,
|
||||
TMS320C64X_REG_B12,
|
||||
TMS320C64X_REG_B13,
|
||||
TMS320C64X_REG_B14,
|
||||
TMS320C64X_REG_B15,
|
||||
TMS320C64X_REG_B16,
|
||||
TMS320C64X_REG_B17,
|
||||
TMS320C64X_REG_B18,
|
||||
TMS320C64X_REG_B19,
|
||||
TMS320C64X_REG_B20,
|
||||
TMS320C64X_REG_B21,
|
||||
TMS320C64X_REG_B22,
|
||||
TMS320C64X_REG_B23,
|
||||
TMS320C64X_REG_B24,
|
||||
TMS320C64X_REG_B25,
|
||||
TMS320C64X_REG_B26,
|
||||
TMS320C64X_REG_B27,
|
||||
TMS320C64X_REG_B28,
|
||||
TMS320C64X_REG_B29,
|
||||
TMS320C64X_REG_B30,
|
||||
TMS320C64X_REG_B31,
|
||||
TMS320C64X_REG_PCE1,
|
||||
|
||||
TMS320C64X_REG_ENDING, // <-- mark the end of the list of registers
|
||||
|
||||
// Alias registers
|
||||
TMS320C64X_REG_EFR = TMS320C64X_REG_ECR,
|
||||
TMS320C64X_REG_IFR = TMS320C64X_REG_ISR,
|
||||
} tms320c64x_reg;
|
||||
|
||||
typedef enum tms320c64x_insn {
|
||||
TMS320C64X_INS_INVALID = 0,
|
||||
|
||||
TMS320C64X_INS_ABS,
|
||||
TMS320C64X_INS_ABS2,
|
||||
TMS320C64X_INS_ADD,
|
||||
TMS320C64X_INS_ADD2,
|
||||
TMS320C64X_INS_ADD4,
|
||||
TMS320C64X_INS_ADDAB,
|
||||
TMS320C64X_INS_ADDAD,
|
||||
TMS320C64X_INS_ADDAH,
|
||||
TMS320C64X_INS_ADDAW,
|
||||
TMS320C64X_INS_ADDK,
|
||||
TMS320C64X_INS_ADDKPC,
|
||||
TMS320C64X_INS_ADDU,
|
||||
TMS320C64X_INS_AND,
|
||||
TMS320C64X_INS_ANDN,
|
||||
TMS320C64X_INS_AVG2,
|
||||
TMS320C64X_INS_AVGU4,
|
||||
TMS320C64X_INS_B,
|
||||
TMS320C64X_INS_BDEC,
|
||||
TMS320C64X_INS_BITC4,
|
||||
TMS320C64X_INS_BNOP,
|
||||
TMS320C64X_INS_BPOS,
|
||||
TMS320C64X_INS_CLR,
|
||||
TMS320C64X_INS_CMPEQ,
|
||||
TMS320C64X_INS_CMPEQ2,
|
||||
TMS320C64X_INS_CMPEQ4,
|
||||
TMS320C64X_INS_CMPGT,
|
||||
TMS320C64X_INS_CMPGT2,
|
||||
TMS320C64X_INS_CMPGTU4,
|
||||
TMS320C64X_INS_CMPLT,
|
||||
TMS320C64X_INS_CMPLTU,
|
||||
TMS320C64X_INS_DEAL,
|
||||
TMS320C64X_INS_DOTP2,
|
||||
TMS320C64X_INS_DOTPN2,
|
||||
TMS320C64X_INS_DOTPNRSU2,
|
||||
TMS320C64X_INS_DOTPRSU2,
|
||||
TMS320C64X_INS_DOTPSU4,
|
||||
TMS320C64X_INS_DOTPU4,
|
||||
TMS320C64X_INS_EXT,
|
||||
TMS320C64X_INS_EXTU,
|
||||
TMS320C64X_INS_GMPGTU,
|
||||
TMS320C64X_INS_GMPY4,
|
||||
TMS320C64X_INS_LDB,
|
||||
TMS320C64X_INS_LDBU,
|
||||
TMS320C64X_INS_LDDW,
|
||||
TMS320C64X_INS_LDH,
|
||||
TMS320C64X_INS_LDHU,
|
||||
TMS320C64X_INS_LDNDW,
|
||||
TMS320C64X_INS_LDNW,
|
||||
TMS320C64X_INS_LDW,
|
||||
TMS320C64X_INS_LMBD,
|
||||
TMS320C64X_INS_MAX2,
|
||||
TMS320C64X_INS_MAXU4,
|
||||
TMS320C64X_INS_MIN2,
|
||||
TMS320C64X_INS_MINU4,
|
||||
TMS320C64X_INS_MPY,
|
||||
TMS320C64X_INS_MPY2,
|
||||
TMS320C64X_INS_MPYH,
|
||||
TMS320C64X_INS_MPYHI,
|
||||
TMS320C64X_INS_MPYHIR,
|
||||
TMS320C64X_INS_MPYHL,
|
||||
TMS320C64X_INS_MPYHLU,
|
||||
TMS320C64X_INS_MPYHSLU,
|
||||
TMS320C64X_INS_MPYHSU,
|
||||
TMS320C64X_INS_MPYHU,
|
||||
TMS320C64X_INS_MPYHULS,
|
||||
TMS320C64X_INS_MPYHUS,
|
||||
TMS320C64X_INS_MPYLH,
|
||||
TMS320C64X_INS_MPYLHU,
|
||||
TMS320C64X_INS_MPYLI,
|
||||
TMS320C64X_INS_MPYLIR,
|
||||
TMS320C64X_INS_MPYLSHU,
|
||||
TMS320C64X_INS_MPYLUHS,
|
||||
TMS320C64X_INS_MPYSU,
|
||||
TMS320C64X_INS_MPYSU4,
|
||||
TMS320C64X_INS_MPYU,
|
||||
TMS320C64X_INS_MPYU4,
|
||||
TMS320C64X_INS_MPYUS,
|
||||
TMS320C64X_INS_MVC,
|
||||
TMS320C64X_INS_MVD,
|
||||
TMS320C64X_INS_MVK,
|
||||
TMS320C64X_INS_MVKL,
|
||||
TMS320C64X_INS_MVKLH,
|
||||
TMS320C64X_INS_NOP,
|
||||
TMS320C64X_INS_NORM,
|
||||
TMS320C64X_INS_OR,
|
||||
TMS320C64X_INS_PACK2,
|
||||
TMS320C64X_INS_PACKH2,
|
||||
TMS320C64X_INS_PACKH4,
|
||||
TMS320C64X_INS_PACKHL2,
|
||||
TMS320C64X_INS_PACKL4,
|
||||
TMS320C64X_INS_PACKLH2,
|
||||
TMS320C64X_INS_ROTL,
|
||||
TMS320C64X_INS_SADD,
|
||||
TMS320C64X_INS_SADD2,
|
||||
TMS320C64X_INS_SADDU4,
|
||||
TMS320C64X_INS_SADDUS2,
|
||||
TMS320C64X_INS_SAT,
|
||||
TMS320C64X_INS_SET,
|
||||
TMS320C64X_INS_SHFL,
|
||||
TMS320C64X_INS_SHL,
|
||||
TMS320C64X_INS_SHLMB,
|
||||
TMS320C64X_INS_SHR,
|
||||
TMS320C64X_INS_SHR2,
|
||||
TMS320C64X_INS_SHRMB,
|
||||
TMS320C64X_INS_SHRU,
|
||||
TMS320C64X_INS_SHRU2,
|
||||
TMS320C64X_INS_SMPY,
|
||||
TMS320C64X_INS_SMPY2,
|
||||
TMS320C64X_INS_SMPYH,
|
||||
TMS320C64X_INS_SMPYHL,
|
||||
TMS320C64X_INS_SMPYLH,
|
||||
TMS320C64X_INS_SPACK2,
|
||||
TMS320C64X_INS_SPACKU4,
|
||||
TMS320C64X_INS_SSHL,
|
||||
TMS320C64X_INS_SSHVL,
|
||||
TMS320C64X_INS_SSHVR,
|
||||
TMS320C64X_INS_SSUB,
|
||||
TMS320C64X_INS_STB,
|
||||
TMS320C64X_INS_STDW,
|
||||
TMS320C64X_INS_STH,
|
||||
TMS320C64X_INS_STNDW,
|
||||
TMS320C64X_INS_STNW,
|
||||
TMS320C64X_INS_STW,
|
||||
TMS320C64X_INS_SUB,
|
||||
TMS320C64X_INS_SUB2,
|
||||
TMS320C64X_INS_SUB4,
|
||||
TMS320C64X_INS_SUBAB,
|
||||
TMS320C64X_INS_SUBABS4,
|
||||
TMS320C64X_INS_SUBAH,
|
||||
TMS320C64X_INS_SUBAW,
|
||||
TMS320C64X_INS_SUBC,
|
||||
TMS320C64X_INS_SUBU,
|
||||
TMS320C64X_INS_SWAP4,
|
||||
TMS320C64X_INS_UNPKHU4,
|
||||
TMS320C64X_INS_UNPKLU4,
|
||||
TMS320C64X_INS_XOR,
|
||||
TMS320C64X_INS_XPND2,
|
||||
TMS320C64X_INS_XPND4,
|
||||
// Aliases
|
||||
TMS320C64X_INS_IDLE,
|
||||
TMS320C64X_INS_MV,
|
||||
TMS320C64X_INS_NEG,
|
||||
TMS320C64X_INS_NOT,
|
||||
TMS320C64X_INS_SWAP2,
|
||||
TMS320C64X_INS_ZERO,
|
||||
|
||||
TMS320C64X_INS_ENDING, // <-- mark the end of the list of instructions
|
||||
} tms320c64x_insn;
|
||||
|
||||
typedef enum tms320c64x_insn_group {
|
||||
TMS320C64X_GRP_INVALID = 0, ///< = CS_GRP_INVALID
|
||||
|
||||
TMS320C64X_GRP_JUMP, ///< = CS_GRP_JUMP
|
||||
|
||||
TMS320C64X_GRP_FUNIT_D = 128,
|
||||
TMS320C64X_GRP_FUNIT_L,
|
||||
TMS320C64X_GRP_FUNIT_M,
|
||||
TMS320C64X_GRP_FUNIT_S,
|
||||
TMS320C64X_GRP_FUNIT_NO,
|
||||
|
||||
TMS320C64X_GRP_ENDING, // <-- mark the end of the list of groups
|
||||
} tms320c64x_insn_group;
|
||||
|
||||
typedef enum tms320c64x_funit {
|
||||
TMS320C64X_FUNIT_INVALID = 0,
|
||||
TMS320C64X_FUNIT_D,
|
||||
TMS320C64X_FUNIT_L,
|
||||
TMS320C64X_FUNIT_M,
|
||||
TMS320C64X_FUNIT_S,
|
||||
TMS320C64X_FUNIT_NO
|
||||
} tms320c64x_funit;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,235 @@
|
||||
#ifndef CAPSTONE_XCORE_H
|
||||
#define CAPSTONE_XCORE_H
|
||||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2014-2015 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4201)
|
||||
#endif
|
||||
|
||||
/// Operand type for instruction's operands
|
||||
typedef enum xcore_op_type {
|
||||
XCORE_OP_INVALID = 0, ///< = CS_OP_INVALID (Uninitialized).
|
||||
XCORE_OP_REG, ///< = CS_OP_REG (Register operand).
|
||||
XCORE_OP_IMM, ///< = CS_OP_IMM (Immediate operand).
|
||||
XCORE_OP_MEM, ///< = CS_OP_MEM (Memory operand).
|
||||
} xcore_op_type;
|
||||
|
||||
/// XCore registers
|
||||
typedef enum xcore_reg {
|
||||
XCORE_REG_INVALID = 0,
|
||||
|
||||
XCORE_REG_CP,
|
||||
XCORE_REG_DP,
|
||||
XCORE_REG_LR,
|
||||
XCORE_REG_SP,
|
||||
XCORE_REG_R0,
|
||||
XCORE_REG_R1,
|
||||
XCORE_REG_R2,
|
||||
XCORE_REG_R3,
|
||||
XCORE_REG_R4,
|
||||
XCORE_REG_R5,
|
||||
XCORE_REG_R6,
|
||||
XCORE_REG_R7,
|
||||
XCORE_REG_R8,
|
||||
XCORE_REG_R9,
|
||||
XCORE_REG_R10,
|
||||
XCORE_REG_R11,
|
||||
|
||||
// pseudo registers
|
||||
XCORE_REG_PC, ///< pc
|
||||
|
||||
// internal thread registers
|
||||
// see The-XMOS-XS1-Architecture(X7879A).pdf
|
||||
XCORE_REG_SCP, ///< save pc
|
||||
XCORE_REG_SSR, //< save status
|
||||
XCORE_REG_ET, //< exception type
|
||||
XCORE_REG_ED, //< exception data
|
||||
XCORE_REG_SED, //< save exception data
|
||||
XCORE_REG_KEP, //< kernel entry pointer
|
||||
XCORE_REG_KSP, //< kernel stack pointer
|
||||
XCORE_REG_ID, //< thread ID
|
||||
|
||||
XCORE_REG_ENDING, // <-- mark the end of the list of registers
|
||||
} xcore_reg;
|
||||
|
||||
/// Instruction's operand referring to memory
|
||||
/// This is associated with XCORE_OP_MEM operand type above
|
||||
typedef struct xcore_op_mem {
|
||||
uint8_t base; ///< base register, can be safely interpreted as
|
||||
///< a value of type `xcore_reg`, but it is only
|
||||
///< one byte wide
|
||||
uint8_t index; ///< index register, same conditions apply here
|
||||
int32_t disp; ///< displacement/offset value
|
||||
int direct; ///< +1: forward, -1: backward
|
||||
} xcore_op_mem;
|
||||
|
||||
/// Instruction operand
|
||||
typedef struct cs_xcore_op {
|
||||
xcore_op_type type; ///< operand type
|
||||
union {
|
||||
xcore_reg reg; ///< register value for REG operand
|
||||
int32_t imm; ///< immediate value for IMM operand
|
||||
xcore_op_mem mem; ///< base/disp value for MEM operand
|
||||
};
|
||||
} cs_xcore_op;
|
||||
|
||||
/// Instruction structure
|
||||
typedef struct cs_xcore {
|
||||
/// Number of operands of this instruction,
|
||||
/// or 0 when instruction has no operand.
|
||||
uint8_t op_count;
|
||||
cs_xcore_op operands[8]; ///< operands for this instruction.
|
||||
} cs_xcore;
|
||||
|
||||
/// XCore instruction
|
||||
typedef enum xcore_insn {
|
||||
XCORE_INS_INVALID = 0,
|
||||
|
||||
XCORE_INS_ADD,
|
||||
XCORE_INS_ANDNOT,
|
||||
XCORE_INS_AND,
|
||||
XCORE_INS_ASHR,
|
||||
XCORE_INS_BAU,
|
||||
XCORE_INS_BITREV,
|
||||
XCORE_INS_BLA,
|
||||
XCORE_INS_BLAT,
|
||||
XCORE_INS_BL,
|
||||
XCORE_INS_BF,
|
||||
XCORE_INS_BT,
|
||||
XCORE_INS_BU,
|
||||
XCORE_INS_BRU,
|
||||
XCORE_INS_BYTEREV,
|
||||
XCORE_INS_CHKCT,
|
||||
XCORE_INS_CLRE,
|
||||
XCORE_INS_CLRPT,
|
||||
XCORE_INS_CLRSR,
|
||||
XCORE_INS_CLZ,
|
||||
XCORE_INS_CRC8,
|
||||
XCORE_INS_CRC32,
|
||||
XCORE_INS_DCALL,
|
||||
XCORE_INS_DENTSP,
|
||||
XCORE_INS_DGETREG,
|
||||
XCORE_INS_DIVS,
|
||||
XCORE_INS_DIVU,
|
||||
XCORE_INS_DRESTSP,
|
||||
XCORE_INS_DRET,
|
||||
XCORE_INS_ECALLF,
|
||||
XCORE_INS_ECALLT,
|
||||
XCORE_INS_EDU,
|
||||
XCORE_INS_EEF,
|
||||
XCORE_INS_EET,
|
||||
XCORE_INS_EEU,
|
||||
XCORE_INS_ENDIN,
|
||||
XCORE_INS_ENTSP,
|
||||
XCORE_INS_EQ,
|
||||
XCORE_INS_EXTDP,
|
||||
XCORE_INS_EXTSP,
|
||||
XCORE_INS_FREER,
|
||||
XCORE_INS_FREET,
|
||||
XCORE_INS_GETD,
|
||||
XCORE_INS_GET,
|
||||
XCORE_INS_GETN,
|
||||
XCORE_INS_GETR,
|
||||
XCORE_INS_GETSR,
|
||||
XCORE_INS_GETST,
|
||||
XCORE_INS_GETTS,
|
||||
XCORE_INS_INCT,
|
||||
XCORE_INS_INIT,
|
||||
XCORE_INS_INPW,
|
||||
XCORE_INS_INSHR,
|
||||
XCORE_INS_INT,
|
||||
XCORE_INS_IN,
|
||||
XCORE_INS_KCALL,
|
||||
XCORE_INS_KENTSP,
|
||||
XCORE_INS_KRESTSP,
|
||||
XCORE_INS_KRET,
|
||||
XCORE_INS_LADD,
|
||||
XCORE_INS_LD16S,
|
||||
XCORE_INS_LD8U,
|
||||
XCORE_INS_LDA16,
|
||||
XCORE_INS_LDAP,
|
||||
XCORE_INS_LDAW,
|
||||
XCORE_INS_LDC,
|
||||
XCORE_INS_LDW,
|
||||
XCORE_INS_LDIVU,
|
||||
XCORE_INS_LMUL,
|
||||
XCORE_INS_LSS,
|
||||
XCORE_INS_LSUB,
|
||||
XCORE_INS_LSU,
|
||||
XCORE_INS_MACCS,
|
||||
XCORE_INS_MACCU,
|
||||
XCORE_INS_MJOIN,
|
||||
XCORE_INS_MKMSK,
|
||||
XCORE_INS_MSYNC,
|
||||
XCORE_INS_MUL,
|
||||
XCORE_INS_NEG,
|
||||
XCORE_INS_NOT,
|
||||
XCORE_INS_OR,
|
||||
XCORE_INS_OUTCT,
|
||||
XCORE_INS_OUTPW,
|
||||
XCORE_INS_OUTSHR,
|
||||
XCORE_INS_OUTT,
|
||||
XCORE_INS_OUT,
|
||||
XCORE_INS_PEEK,
|
||||
XCORE_INS_REMS,
|
||||
XCORE_INS_REMU,
|
||||
XCORE_INS_RETSP,
|
||||
XCORE_INS_SETCLK,
|
||||
XCORE_INS_SET,
|
||||
XCORE_INS_SETC,
|
||||
XCORE_INS_SETD,
|
||||
XCORE_INS_SETEV,
|
||||
XCORE_INS_SETN,
|
||||
XCORE_INS_SETPSC,
|
||||
XCORE_INS_SETPT,
|
||||
XCORE_INS_SETRDY,
|
||||
XCORE_INS_SETSR,
|
||||
XCORE_INS_SETTW,
|
||||
XCORE_INS_SETV,
|
||||
XCORE_INS_SEXT,
|
||||
XCORE_INS_SHL,
|
||||
XCORE_INS_SHR,
|
||||
XCORE_INS_SSYNC,
|
||||
XCORE_INS_ST16,
|
||||
XCORE_INS_ST8,
|
||||
XCORE_INS_STW,
|
||||
XCORE_INS_SUB,
|
||||
XCORE_INS_SYNCR,
|
||||
XCORE_INS_TESTCT,
|
||||
XCORE_INS_TESTLCL,
|
||||
XCORE_INS_TESTWCT,
|
||||
XCORE_INS_TSETMR,
|
||||
XCORE_INS_START,
|
||||
XCORE_INS_WAITEF,
|
||||
XCORE_INS_WAITET,
|
||||
XCORE_INS_WAITEU,
|
||||
XCORE_INS_XOR,
|
||||
XCORE_INS_ZEXT,
|
||||
|
||||
XCORE_INS_ENDING, // <-- mark the end of the list of instructions
|
||||
} xcore_insn;
|
||||
|
||||
/// Group of XCore instructions
|
||||
typedef enum xcore_insn_group {
|
||||
XCORE_GRP_INVALID = 0, ///< = CS_GRP_INVALID
|
||||
|
||||
// Generic groups
|
||||
// all jump instructions (conditional+direct+indirect jumps)
|
||||
XCORE_GRP_JUMP, ///< = CS_GRP_JUMP
|
||||
|
||||
XCORE_GRP_ENDING, // <-- mark the end of the list of groups
|
||||
} xcore_insn_group;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,110 @@
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Axel Souchet & Nguyen Anh Quynh, 2014 */
|
||||
|
||||
#ifndef CAPSTONE_PLATFORM_H
|
||||
#define CAPSTONE_PLATFORM_H
|
||||
|
||||
// handle C99 issue (for pre-2013 VisualStudio)
|
||||
#if !defined(__CYGWIN__) && !defined(__MINGW32__) && !defined(__MINGW64__) && (defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64))
|
||||
// MSVC
|
||||
|
||||
// stdbool.h
|
||||
#if (_MSC_VER < 1800) || defined(_KERNEL_MODE)
|
||||
// this system does not have stdbool.h
|
||||
#ifndef __cplusplus
|
||||
typedef unsigned char bool;
|
||||
#define false 0
|
||||
#define true 1
|
||||
#endif
|
||||
|
||||
#else
|
||||
// VisualStudio 2013+ -> C99 is supported
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#else
|
||||
// not MSVC -> C99 is supported
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
|
||||
// handle C99 issue (for pre-2013 VisualStudio)
|
||||
#if defined(CAPSTONE_HAS_OSXKERNEL) || (defined(_MSC_VER) && (_MSC_VER <= 1700 || defined(_KERNEL_MODE)))
|
||||
// this system does not have inttypes.h
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1600 || defined(_KERNEL_MODE))
|
||||
// this system does not have stdint.h
|
||||
typedef signed char int8_t;
|
||||
typedef signed short int16_t;
|
||||
typedef signed int int32_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef signed long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
|
||||
#define INT8_MIN (-127i8 - 1)
|
||||
#define INT16_MIN (-32767i16 - 1)
|
||||
#define INT32_MIN (-2147483647i32 - 1)
|
||||
#define INT64_MIN (-9223372036854775807i64 - 1)
|
||||
#define INT8_MAX 127i8
|
||||
#define INT16_MAX 32767i16
|
||||
#define INT32_MAX 2147483647i32
|
||||
#define INT64_MAX 9223372036854775807i64
|
||||
#define UINT8_MAX 0xffui8
|
||||
#define UINT16_MAX 0xffffui16
|
||||
#define UINT32_MAX 0xffffffffui32
|
||||
#define UINT64_MAX 0xffffffffffffffffui64
|
||||
#endif
|
||||
|
||||
#define __PRI_8_LENGTH_MODIFIER__ "hh"
|
||||
#define __PRI_64_LENGTH_MODIFIER__ "ll"
|
||||
|
||||
#define PRId8 __PRI_8_LENGTH_MODIFIER__ "d"
|
||||
#define PRIi8 __PRI_8_LENGTH_MODIFIER__ "i"
|
||||
#define PRIo8 __PRI_8_LENGTH_MODIFIER__ "o"
|
||||
#define PRIu8 __PRI_8_LENGTH_MODIFIER__ "u"
|
||||
#define PRIx8 __PRI_8_LENGTH_MODIFIER__ "x"
|
||||
#define PRIX8 __PRI_8_LENGTH_MODIFIER__ "X"
|
||||
|
||||
#define PRId16 "hd"
|
||||
#define PRIi16 "hi"
|
||||
#define PRIo16 "ho"
|
||||
#define PRIu16 "hu"
|
||||
#define PRIx16 "hx"
|
||||
#define PRIX16 "hX"
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1700
|
||||
#define PRId32 "ld"
|
||||
#define PRIi32 "li"
|
||||
#define PRIo32 "lo"
|
||||
#define PRIu32 "lu"
|
||||
#define PRIx32 "lx"
|
||||
#define PRIX32 "lX"
|
||||
#else // OSX
|
||||
#define PRId32 "d"
|
||||
#define PRIi32 "i"
|
||||
#define PRIo32 "o"
|
||||
#define PRIu32 "u"
|
||||
#define PRIx32 "x"
|
||||
#define PRIX32 "X"
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1700
|
||||
// redefine functions from inttypes.h used in cstool
|
||||
#define strtoull _strtoui64
|
||||
#endif
|
||||
|
||||
#define PRId64 __PRI_64_LENGTH_MODIFIER__ "d"
|
||||
#define PRIi64 __PRI_64_LENGTH_MODIFIER__ "i"
|
||||
#define PRIo64 __PRI_64_LENGTH_MODIFIER__ "o"
|
||||
#define PRIu64 __PRI_64_LENGTH_MODIFIER__ "u"
|
||||
#define PRIx64 __PRI_64_LENGTH_MODIFIER__ "x"
|
||||
#define PRIX64 __PRI_64_LENGTH_MODIFIER__ "X"
|
||||
|
||||
#else
|
||||
// this system has inttypes.h by default
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
#if defined(_MSC_VER) && defined(_WIN32_WCE) && (_WIN32_WCE < 0x800) && !defined(__INTRIN_H_) && !defined(_INTRIN)
|
||||
#define _STDINT
|
||||
|
||||
#ifdef _M_ARM
|
||||
#include <armintr.h>
|
||||
#if (_WIN32_WCE >= 0x700) && defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__)
|
||||
#include <arm_neon.h>
|
||||
#endif
|
||||
#endif // _M_ARM
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,133 @@
|
||||
|
||||
#if defined(_MSC_VER) && defined(_WIN32_WCE) && (_WIN32_WCE < 0x800) && !defined(_STDINT_H_) && !defined(_STDINT)
|
||||
#define _STDINT
|
||||
|
||||
typedef __int8
|
||||
int8_t,
|
||||
int_least8_t;
|
||||
|
||||
typedef __int16
|
||||
int16_t,
|
||||
int_least16_t;
|
||||
|
||||
typedef __int32
|
||||
int32_t,
|
||||
int_least32_t,
|
||||
int_fast8_t,
|
||||
int_fast16_t,
|
||||
int_fast32_t;
|
||||
|
||||
typedef __int64
|
||||
int64_t,
|
||||
intmax_t,
|
||||
int_least64_t,
|
||||
int_fast64_t;
|
||||
|
||||
typedef unsigned __int8
|
||||
uint8_t,
|
||||
uint_least8_t;
|
||||
|
||||
typedef unsigned __int16
|
||||
uint16_t,
|
||||
uint_least16_t;
|
||||
|
||||
typedef unsigned __int32
|
||||
uint32_t,
|
||||
uint_least32_t,
|
||||
uint_fast8_t,
|
||||
uint_fast16_t,
|
||||
uint_fast32_t;
|
||||
|
||||
typedef unsigned __int64
|
||||
uint64_t,
|
||||
uintmax_t,
|
||||
uint_least64_t,
|
||||
uint_fast64_t;
|
||||
|
||||
#ifndef _INTPTR_T_DEFINED
|
||||
#define _INTPTR_T_DEFINED
|
||||
typedef __int32 intptr_t;
|
||||
#endif
|
||||
|
||||
#ifndef _UINTPTR_T_DEFINED
|
||||
#define _UINTPTR_T_DEFINED
|
||||
typedef unsigned __int32 uintptr_t;
|
||||
#endif
|
||||
|
||||
#define INT8_MIN (-127i8 - 1)
|
||||
#define INT16_MIN (-32767i16 - 1)
|
||||
#define INT32_MIN (-2147483647i32 - 1)
|
||||
#define INT64_MIN (-9223372036854775807i64 - 1)
|
||||
#define INT8_MAX 127i8
|
||||
#define INT16_MAX 32767i16
|
||||
#define INT32_MAX 2147483647i32
|
||||
#define INT64_MAX 9223372036854775807i64
|
||||
#define UINT8_MAX 0xffui8
|
||||
#define UINT16_MAX 0xffffui16
|
||||
#define UINT32_MAX 0xffffffffui32
|
||||
#define UINT64_MAX 0xffffffffffffffffui64
|
||||
|
||||
#define INT_LEAST8_MIN INT8_MIN
|
||||
#define INT_LEAST16_MIN INT16_MIN
|
||||
#define INT_LEAST32_MIN INT32_MIN
|
||||
#define INT_LEAST64_MIN INT64_MIN
|
||||
#define INT_LEAST8_MAX INT8_MAX
|
||||
#define INT_LEAST16_MAX INT16_MAX
|
||||
#define INT_LEAST32_MAX INT32_MAX
|
||||
#define INT_LEAST64_MAX INT64_MAX
|
||||
#define UINT_LEAST8_MAX UINT8_MAX
|
||||
#define UINT_LEAST16_MAX UINT16_MAX
|
||||
#define UINT_LEAST32_MAX UINT32_MAX
|
||||
#define UINT_LEAST64_MAX UINT64_MAX
|
||||
|
||||
#define INT_FAST8_MIN INT8_MIN
|
||||
#define INT_FAST16_MIN INT32_MIN
|
||||
#define INT_FAST32_MIN INT32_MIN
|
||||
#define INT_FAST64_MIN INT64_MIN
|
||||
#define INT_FAST8_MAX INT8_MAX
|
||||
#define INT_FAST16_MAX INT32_MAX
|
||||
#define INT_FAST32_MAX INT32_MAX
|
||||
#define INT_FAST64_MAX INT64_MAX
|
||||
#define UINT_FAST8_MAX UINT8_MAX
|
||||
#define UINT_FAST16_MAX UINT32_MAX
|
||||
#define UINT_FAST32_MAX UINT32_MAX
|
||||
#define UINT_FAST64_MAX UINT64_MAX
|
||||
|
||||
#define INTPTR_MIN INT32_MIN
|
||||
#define INTPTR_MAX INT32_MAX
|
||||
#define UINTPTR_MAX UINT32_MAX
|
||||
|
||||
#define INTMAX_MIN INT64_MIN
|
||||
#define INTMAX_MAX INT64_MAX
|
||||
#define UINTMAX_MAX UINT64_MAX
|
||||
|
||||
#define PTRDIFF_MIN INTPTR_MIN
|
||||
#define PTRDIFF_MAX INTPTR_MAX
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
#define SIZE_MAX UINTPTR_MAX
|
||||
#endif
|
||||
|
||||
#define SIG_ATOMIC_MIN INT32_MIN
|
||||
#define SIG_ATOMIC_MAX INT32_MAX
|
||||
|
||||
#define WCHAR_MIN 0x0000
|
||||
#define WCHAR_MAX 0xffff
|
||||
|
||||
#define WINT_MIN 0x0000
|
||||
#define WINT_MAX 0xffff
|
||||
|
||||
#define INT8_C(x) (x)
|
||||
#define INT16_C(x) (x)
|
||||
#define INT32_C(x) (x)
|
||||
#define INT64_C(x) (x ## LL)
|
||||
|
||||
#define UINT8_C(x) (x)
|
||||
#define UINT16_C(x) (x)
|
||||
#define UINT32_C(x) (x ## U)
|
||||
#define UINT64_C(x) (x ## ULL)
|
||||
|
||||
#define INTMAX_C(x) INT64_C(x)
|
||||
#define UINTMAX_C(x) UINT64_C(x)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,135 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <windows.h>
|
||||
|
||||
namespace Helper {
|
||||
|
||||
bool ConvertToUTF8(LPCSTR from, std::string& to) {
|
||||
bool bSuccess = false;
|
||||
int len = 0;
|
||||
LPWSTR lpUnicodeString = nullptr;
|
||||
|
||||
len = MultiByteToWideChar(CP_ACP, NULL, from, -1, NULL, 0);
|
||||
if (len == 0)
|
||||
goto ON_ConvertToUTF8_0_ERROR;
|
||||
|
||||
lpUnicodeString = reinterpret_cast<LPWSTR>(HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
len * sizeof(WCHAR)));
|
||||
if (lpUnicodeString == nullptr)
|
||||
goto ON_ConvertToUTF8_0_ERROR;
|
||||
|
||||
if (!MultiByteToWideChar(CP_ACP, NULL, from, -1, lpUnicodeString, len))
|
||||
goto ON_ConvertToUTF8_0_ERROR;
|
||||
|
||||
len = WideCharToMultiByte(CP_UTF8, NULL, lpUnicodeString, -1, NULL, 0, NULL, NULL);
|
||||
if (len == 0)
|
||||
goto ON_ConvertToUTF8_0_ERROR;
|
||||
|
||||
to.resize(len);
|
||||
if (!WideCharToMultiByte(CP_UTF8, NULL, lpUnicodeString, -1, to.data(), len, NULL, NULL))
|
||||
goto ON_ConvertToUTF8_0_ERROR;
|
||||
|
||||
while (to.back() == 0)
|
||||
to.pop_back();
|
||||
|
||||
bSuccess = true;
|
||||
|
||||
ON_ConvertToUTF8_0_ERROR:
|
||||
if (lpUnicodeString)
|
||||
HeapFree(GetProcessHeap(), NULL, lpUnicodeString);
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
bool ConvertToUTF8(LPCWSTR from, std::string& to) {
|
||||
bool bSuccess = false;
|
||||
int len = 0;
|
||||
|
||||
len = WideCharToMultiByte(CP_UTF8, NULL, from, -1, NULL, 0, NULL, NULL);
|
||||
if (len == 0)
|
||||
goto ON_ConvertToUTF8_1_ERROR;
|
||||
|
||||
to.resize(len);
|
||||
if (!WideCharToMultiByte(CP_UTF8, NULL, from, -1, to.data(), len, NULL, NULL))
|
||||
goto ON_ConvertToUTF8_1_ERROR;
|
||||
|
||||
while (to.back() == 0)
|
||||
to.pop_back();
|
||||
|
||||
bSuccess = true;
|
||||
|
||||
ON_ConvertToUTF8_1_ERROR:
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
bool ConvertToUTF8(std::string& str) {
|
||||
bool bSuccess = false;
|
||||
|
||||
std::string temp;
|
||||
bSuccess = ConvertToUTF8(str.c_str(), temp);
|
||||
if (!bSuccess)
|
||||
return false;
|
||||
|
||||
str = temp;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string Base64Encode(const std::vector<uint8_t>& bytes) {
|
||||
std::string Result;
|
||||
DWORD pcchString = 0;
|
||||
|
||||
if (bytes.empty())
|
||||
return Result;
|
||||
|
||||
CryptBinaryToStringA(bytes.data(),
|
||||
bytes.size(),
|
||||
CRYPT_STRING_BASE64,
|
||||
NULL,
|
||||
&pcchString);
|
||||
if (pcchString == 0)
|
||||
return Result;
|
||||
|
||||
Result.resize(pcchString + 1);
|
||||
|
||||
if (!CryptBinaryToStringA(bytes.data(),
|
||||
bytes.size(),
|
||||
CRYPT_STRING_BASE64,
|
||||
Result.data(),
|
||||
&pcchString))
|
||||
Result.clear();
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> Base64Decode(std::string& str) {
|
||||
std::vector<uint8_t> Result;
|
||||
DWORD pcbBinary = 0;
|
||||
|
||||
if (str.empty())
|
||||
return Result;
|
||||
|
||||
CryptStringToBinaryA(str.c_str(),
|
||||
NULL,
|
||||
CRYPT_STRING_BASE64,
|
||||
NULL,
|
||||
&pcbBinary,
|
||||
NULL,
|
||||
NULL);
|
||||
if (pcbBinary == 0)
|
||||
return Result;
|
||||
|
||||
Result.resize(pcbBinary);
|
||||
|
||||
if (!CryptStringToBinaryA(str.c_str(),
|
||||
NULL,
|
||||
CRYPT_STRING_BASE64,
|
||||
Result.data(),
|
||||
&pcbBinary,
|
||||
NULL,
|
||||
NULL))
|
||||
Result.clear();
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -38,93 +38,6 @@ private:
|
||||
std::uniform_int_distribution<int> rand;
|
||||
uint8_t data[10];
|
||||
|
||||
void SetLanguageSigature(Language _language) {
|
||||
switch (_language) {
|
||||
case Language::English:
|
||||
data[5] = 0xAC; // Must be 0xAC for English version.
|
||||
data[6] = 0x88; // Must be 0x88 for English version.
|
||||
break;
|
||||
case Language::SimplifiedChinese:
|
||||
data[5] = 0xCE; // Must be 0xCE for Simplified Chinese version.
|
||||
data[6] = 0x32; // Must be 0x32 for Simplified Chinese version.
|
||||
break;
|
||||
case Language::TraditionalChinese:
|
||||
data[5] = 0xAA; // Must be 0xAA for Traditional Chinese version.
|
||||
data[6] = 0x99; // Must be 0x99 for Traditional Chinese version.
|
||||
break;
|
||||
case Language::Japanese:
|
||||
data[5] = 0xAD; // Must be 0xAD for Japanese version. Discoverer: @dragonflylee
|
||||
data[6] = 0x82; // Must be 0x82 for Japanese version. Discoverer: @dragonflylee
|
||||
break;
|
||||
case Language::Polish:
|
||||
data[5] = 0xBB; // Must be 0xBB for Polish version. Discoverer: @dragonflylee
|
||||
data[6] = 0x55; // Must be 0x55 for Polish version. Discoverer: @dragonflylee
|
||||
break;
|
||||
case Language::Spanish:
|
||||
data[5] = 0xAE; // Must be 0xAE for Spanish version. Discoverer: @dragonflylee
|
||||
data[6] = 0x10; // Must be 0x10 for Spanish version. Discoverer: @dragonflylee
|
||||
break;
|
||||
case Language::French:
|
||||
data[5] = 0xFA; // Must be 0xFA for French version. Discoverer: @Deltafox79
|
||||
data[6] = 0x20; // Must be 0x20 for French version. Discoverer: @Deltafox79
|
||||
break;
|
||||
case Language::German:
|
||||
data[5] = 0xB1; // Must be 0xB1 for German version. Discoverer: @dragonflylee
|
||||
data[6] = 0x60; // Must be 0x60 for German version. Discoverer: @dragonflylee
|
||||
break;
|
||||
case Language::Korean:
|
||||
data[5] = 0xB5; // Must be 0xB5 for Korean version. Discoverer: @dragonflylee
|
||||
data[6] = 0x60; // Must be 0x60 for Korean version. Discoverer: @dragonflylee
|
||||
break;
|
||||
case Language::Russian:
|
||||
data[5] = 0xEE; // Must be 0xB5 for Russian version. Discoverer: @dragonflylee
|
||||
data[6] = 0x16; // Must be 0x60 for Russian version. Discoverer: @dragonflylee
|
||||
break;
|
||||
case Language::Portuguese:
|
||||
data[5] = 0xCD; // Must be 0xCD for Portuguese version. Discoverer: @dragonflylee
|
||||
data[6] = 0x49; // Must be 0x49 for Portuguese version. Discoverer: @dragonflylee
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetProductSignature(Product _product) {
|
||||
switch (_product) {
|
||||
case Product::DataModeler:
|
||||
data[7] = 0x47;
|
||||
break;
|
||||
case Product::Premium:
|
||||
data[7] = 0x65;
|
||||
break;
|
||||
case Product::MySQL:
|
||||
data[7] = 0x68;
|
||||
break;
|
||||
case Product::PostgreSQL:
|
||||
data[7] = 0x6C;
|
||||
break;
|
||||
case Product::Oracle:
|
||||
data[7] = 0x70;
|
||||
break;
|
||||
case Product::SQLServer:
|
||||
data[7] = 0x74;
|
||||
break;
|
||||
case Product::SQLite:
|
||||
data[7] = 0x78;
|
||||
break;
|
||||
case Product::MariaDB:
|
||||
data[7] = 0x7C;
|
||||
break;
|
||||
case Product::MongoDB:
|
||||
data[7] = 0x80;
|
||||
break;
|
||||
case Product::ReportViewer:
|
||||
data[7] = 0xb;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DoEncrypt() {
|
||||
const_DES_cblock DESKey = { 0x64, 0xAD, 0xF3, 0x2F, 0xAE, 0xF2, 0x1A, 0x27 };
|
||||
DES_key_schedule schedule;
|
||||
@@ -145,15 +58,111 @@ public:
|
||||
data[1] = 0x2A;
|
||||
}
|
||||
|
||||
void Generate(uint8_t version, Language language, Product product) {
|
||||
void SetLanguageSignature(Language _language) {
|
||||
switch (_language) {
|
||||
case Language::English:
|
||||
data[5] = 0xAC; // Must be 0xAC for English version.
|
||||
data[6] = 0x88; // Must be 0x88 for English version.
|
||||
break;
|
||||
case Language::SimplifiedChinese:
|
||||
data[5] = 0xCE; // Must be 0xCE for Simplified Chinese version.
|
||||
data[6] = 0x32; // Must be 0x32 for Simplified Chinese version.
|
||||
break;
|
||||
case Language::TraditionalChinese:
|
||||
data[5] = 0xAA; // Must be 0xAA for Traditional Chinese version.
|
||||
data[6] = 0x99; // Must be 0x99 for Traditional Chinese version.
|
||||
break;
|
||||
case Language::Japanese:
|
||||
data[5] = 0xAD; // Must be 0xAD for Japanese version. Discoverer: @dragonflylee
|
||||
data[6] = 0x82; // Must be 0x82 for Japanese version. Discoverer: @dragonflylee
|
||||
break;
|
||||
case Language::Polish:
|
||||
data[5] = 0xBB; // Must be 0xBB for Polish version. Discoverer: @dragonflylee
|
||||
data[6] = 0x55; // Must be 0x55 for Polish version. Discoverer: @dragonflylee
|
||||
break;
|
||||
case Language::Spanish:
|
||||
data[5] = 0xAE; // Must be 0xAE for Spanish version. Discoverer: @dragonflylee
|
||||
data[6] = 0x10; // Must be 0x10 for Spanish version. Discoverer: @dragonflylee
|
||||
break;
|
||||
case Language::French:
|
||||
data[5] = 0xFA; // Must be 0xFA for French version. Discoverer: @Deltafox79
|
||||
data[6] = 0x20; // Must be 0x20 for French version. Discoverer: @Deltafox79
|
||||
break;
|
||||
case Language::German:
|
||||
data[5] = 0xB1; // Must be 0xB1 for German version. Discoverer: @dragonflylee
|
||||
data[6] = 0x60; // Must be 0x60 for German version. Discoverer: @dragonflylee
|
||||
break;
|
||||
case Language::Korean:
|
||||
data[5] = 0xB5; // Must be 0xB5 for Korean version. Discoverer: @dragonflylee
|
||||
data[6] = 0x60; // Must be 0x60 for Korean version. Discoverer: @dragonflylee
|
||||
break;
|
||||
case Language::Russian:
|
||||
data[5] = 0xEE; // Must be 0xB5 for Russian version. Discoverer: @dragonflylee
|
||||
data[6] = 0x16; // Must be 0x60 for Russian version. Discoverer: @dragonflylee
|
||||
break;
|
||||
case Language::Portuguese:
|
||||
data[5] = 0xCD; // Must be 0xCD for Portuguese version. Discoverer: @dragonflylee
|
||||
data[6] = 0x49; // Must be 0x49 for Portuguese version. Discoverer: @dragonflylee
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetLanguageSignature(uint8_t value0, uint8_t value1) {
|
||||
data[5] = value0;
|
||||
data[6] = value1;
|
||||
}
|
||||
|
||||
void SetProductSignature(Product _product) {
|
||||
switch (_product) {
|
||||
case Product::DataModeler:
|
||||
data[7] = 0x47;
|
||||
break;
|
||||
case Product::Premium:
|
||||
data[7] = 0x65;
|
||||
break;
|
||||
case Product::MySQL:
|
||||
data[7] = 0x68;
|
||||
break;
|
||||
case Product::PostgreSQL:
|
||||
data[7] = 0x6C;
|
||||
break;
|
||||
case Product::Oracle:
|
||||
data[7] = 0x70;
|
||||
break;
|
||||
case Product::SQLServer:
|
||||
data[7] = 0x74;
|
||||
break;
|
||||
case Product::SQLite:
|
||||
data[7] = 0x78;
|
||||
break;
|
||||
case Product::MariaDB:
|
||||
data[7] = 0x7C;
|
||||
break;
|
||||
case Product::MongoDB:
|
||||
data[7] = 0x80;
|
||||
break;
|
||||
case Product::ReportViewer:
|
||||
data[7] = 0xb;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetProductSignature(uint8_t value) {
|
||||
data[7] = value;
|
||||
}
|
||||
|
||||
void SetVersion(uint8_t version) {
|
||||
data[8] = version << 4;
|
||||
}
|
||||
|
||||
void Generate() {
|
||||
data[2] = rand(rand_eng);
|
||||
data[3] = rand(rand_eng);
|
||||
data[4] = rand(rand_eng);
|
||||
SetLanguageSigature(language);
|
||||
SetProductSignature(product);
|
||||
data[8] = version << 4;
|
||||
data[9] = 0x32;
|
||||
|
||||
DoEncrypt();
|
||||
}
|
||||
|
||||
@@ -161,7 +170,7 @@ public:
|
||||
std::string Key;
|
||||
const char EncodeTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
||||
|
||||
Key.resize(16 + 1);
|
||||
Key.resize(16);
|
||||
Key[0] = EncodeTable[data[0] >> 3];
|
||||
Key[1] = EncodeTable[(data[0] & 0x07) << 2 | data[1] >> 6];
|
||||
Key[2] = EncodeTable[data[1] >> 1 & 0x1F];
|
||||
@@ -179,20 +188,21 @@ public:
|
||||
Key[13] = EncodeTable[data[8] >> 2 & 0x1F];
|
||||
Key[14] = EncodeTable[data[8] << 3 & 0x1F | data[9] >> 5];
|
||||
Key[15] = EncodeTable[data[9] & 0x1F];
|
||||
Key[16] = 0;
|
||||
|
||||
return Key;
|
||||
}
|
||||
|
||||
std::string GetFormatedKey() const {
|
||||
std::string Key = GetKey();
|
||||
|
||||
auto ptr = Key.begin() + 4;
|
||||
Key.insert(ptr++, '-');
|
||||
|
||||
ptr = Key.insert(ptr, '-');
|
||||
ptr++;
|
||||
ptr += 4;
|
||||
Key.insert(ptr++, '-');
|
||||
ptr = Key.insert(ptr, '-');
|
||||
ptr++;
|
||||
ptr += 4;
|
||||
Key.insert(ptr++, '-');
|
||||
Key.insert(ptr, '-');
|
||||
|
||||
return Key;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,342 @@
|
||||
#include <iostream>
|
||||
#include <ctime>
|
||||
#include <windows.h>
|
||||
|
||||
#include "RSACipher.hpp"
|
||||
#include "NavicatKeygen.hpp"
|
||||
|
||||
#include <rapidjson/document.h>
|
||||
#include <rapidjson/writer.h>
|
||||
#include <rapidjson/stringbuffer.h>
|
||||
|
||||
namespace Helper {
|
||||
bool ConvertToUTF8(LPCSTR from, std::string& to);
|
||||
bool ConvertToUTF8(LPCWSTR from, std::string& to);
|
||||
bool ConvertToUTF8(std::string& str);
|
||||
|
||||
std::string Base64Encode(const std::vector<uint8_t>& bytes);
|
||||
std::vector<uint8_t> Base64Decode(std::string& str);
|
||||
|
||||
template<int min_num, int max_num>
|
||||
bool ReadNumber(int& num, const char* msg, const char* err_msg) {
|
||||
int temp;
|
||||
std::string input;
|
||||
while (true) {
|
||||
std::cout << msg;
|
||||
if (!std::getline(std::cin, input))
|
||||
return false;
|
||||
|
||||
try {
|
||||
temp = std::stoi(input, nullptr, 0);
|
||||
if (min_num <= temp && temp <= max_num) {
|
||||
num = temp;
|
||||
return true;
|
||||
} else {
|
||||
throw std::invalid_argument("Invalid number");
|
||||
}
|
||||
} catch (...) {
|
||||
std::cout << err_msg << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define MODE_SIMPLE 1
|
||||
#define MODE_ADVANCED 2
|
||||
#define FLAG_BIN 1
|
||||
#define FLAG_TEXT 2
|
||||
void Process(RSACipher* cipher, int mode, int flag) {
|
||||
std::string input;
|
||||
int num;
|
||||
|
||||
NavicatKeygen::Product product;
|
||||
NavicatKeygen::Language language;
|
||||
uint8_t product0;
|
||||
uint8_t language0, language1;
|
||||
uint8_t version;
|
||||
NavicatKeygen keygen;
|
||||
std::string username;
|
||||
std::string organization;
|
||||
|
||||
std::string RequestCode_b64;
|
||||
std::vector<uint8_t> RequestCode;
|
||||
char RequestInfo[256] = {};
|
||||
char ResponseInfo[256] = {};
|
||||
std::vector<uint8_t> ResponseCode;
|
||||
std::string ResponseCode_b64;
|
||||
|
||||
rapidjson::Document json;
|
||||
rapidjson::Value N_Key;
|
||||
rapidjson::Value N_Value;
|
||||
rapidjson::Value O_Key;
|
||||
rapidjson::Value O_Value;
|
||||
rapidjson::Value T_Key;
|
||||
rapidjson::Value T_Value;
|
||||
rapidjson::StringBuffer buffer;
|
||||
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
|
||||
|
||||
if (mode == MODE_SIMPLE) {
|
||||
std::cout << "Select Navicat product:" << std::endl
|
||||
<< "0. DataModeler" << std::endl
|
||||
<< "1. Premium" << std::endl
|
||||
<< "2. MySQL" << std::endl
|
||||
<< "3. PostgreSQL" << std::endl
|
||||
<< "4. Oracle" << std::endl
|
||||
<< "5. SQLServer" << std::endl
|
||||
<< "6. SQLite" << std::endl
|
||||
<< "7. MariaDB" << std::endl
|
||||
<< "8. MongoDB" << std::endl
|
||||
<< "9. ReportViewer" << std::endl
|
||||
<< std::endl;
|
||||
|
||||
if (!Helper::ReadNumber<0, 9>(num,
|
||||
"(Input index)> ",
|
||||
"Invalid index.")) {
|
||||
return;
|
||||
}
|
||||
product = static_cast<NavicatKeygen::Product>(num);
|
||||
|
||||
std::cout << std::endl;
|
||||
std::cout << "Select product language:" << std::endl
|
||||
<< "0. English" << std::endl
|
||||
<< "1. Simplified Chinese" << std::endl
|
||||
<< "2. Traditional Chinese" << std::endl
|
||||
<< "3. Japanese" << std::endl
|
||||
<< "4. Polish" << std::endl
|
||||
<< "5. Spanish" << std::endl
|
||||
<< "6. French" << std::endl
|
||||
<< "7. German" << std::endl
|
||||
<< "8. Korean" << std::endl
|
||||
<< "9. Russian" << std::endl
|
||||
<< "10. Portuguese" << std::endl
|
||||
<< std::endl;
|
||||
|
||||
if (!Helper::ReadNumber<0, 10>(num,
|
||||
"(Input index)> ",
|
||||
"Invalid index.")) {
|
||||
return;
|
||||
}
|
||||
language = static_cast<NavicatKeygen::Language>(num);
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
keygen.SetProductSignature(product);
|
||||
keygen.SetLanguageSignature(language);
|
||||
}
|
||||
|
||||
if (mode == MODE_ADVANCED) {
|
||||
|
||||
if (!Helper::ReadNumber<0, 255>(num,
|
||||
"(Navicat Product ID, 0x00 ~ 0xFF)> ",
|
||||
"Invalid number.")) {
|
||||
return;
|
||||
}
|
||||
product0 = static_cast<uint8_t>(num);
|
||||
|
||||
if (!Helper::ReadNumber<0, 255>(num,
|
||||
"(Navicat Language Signature 0, 0x00 ~ 0xFF)> ",
|
||||
"Invalid number.")) {
|
||||
return;
|
||||
}
|
||||
language0 = static_cast<uint8_t>(num);
|
||||
|
||||
if (!Helper::ReadNumber<0, 255>(num,
|
||||
"(Navicat Language Signature 1, 0x00 ~ 0xFF)> ",
|
||||
"Invalid number.")) {
|
||||
return;
|
||||
}
|
||||
language1 = static_cast<uint8_t>(num);
|
||||
|
||||
keygen.SetProductSignature(product0);
|
||||
keygen.SetLanguageSignature(language0, language1);
|
||||
}
|
||||
|
||||
if (!Helper::ReadNumber<0, 16 - 1>(num,
|
||||
"(Input major version number, range: 0 ~ 15, default: 12)> ",
|
||||
"Invalid number.")) {
|
||||
return;
|
||||
}
|
||||
version = static_cast<uint8_t>(num);
|
||||
keygen.SetVersion(version);
|
||||
|
||||
keygen.Generate();
|
||||
std::cout << std::endl;
|
||||
std::cout << "Serial number:" << std::endl;
|
||||
std::cout << keygen.GetFormatedKey() << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "Your name: ";
|
||||
if (!std::getline(std::cin, username))
|
||||
return;
|
||||
if (!Helper::ConvertToUTF8(username)) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "ERROR: ConvertToUTF8 fails." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "Your organization: ";
|
||||
if (!std::getline(std::cin, organization))
|
||||
return;
|
||||
if (!Helper::ConvertToUTF8(organization)) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "ERROR: ConvertToUTF8 fails." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
if (flag == FLAG_TEXT) {
|
||||
std::cout << "Input request code (in Base64), input empty line to end:" << std::endl;
|
||||
while (true) {
|
||||
std::string temp;
|
||||
if (!std::getline(std::cin, temp))
|
||||
return;
|
||||
|
||||
if (temp.empty())
|
||||
break;
|
||||
|
||||
RequestCode_b64 += temp;
|
||||
}
|
||||
|
||||
RequestCode = Helper::Base64Decode(RequestCode_b64);
|
||||
if (RequestCode.empty()) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "ERROR: Base64Decode fails." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cipher->Decrypt(RequestCode.data(),
|
||||
RequestCode.size(),
|
||||
RequestInfo,
|
||||
RSA_PKCS1_PADDING)) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "ERROR: Decrypt<RSACipher::KeyType::PrivateKey> fails." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "Request Info:" << std::endl;
|
||||
std::cout << RequestInfo << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
json.Parse(RequestInfo);
|
||||
json.RemoveMember("P"); // remove Platform info
|
||||
|
||||
|
||||
N_Key.SetString("N", 1);
|
||||
N_Value.SetString(username.c_str(), username.length());
|
||||
O_Key.SetString("O", 1);
|
||||
O_Value.SetString(organization.c_str(), organization.length());
|
||||
T_Key.SetString("T", 1);
|
||||
T_Value.SetUint(std::time(nullptr));
|
||||
|
||||
json.AddMember(N_Key, N_Value, json.GetAllocator());
|
||||
json.AddMember(O_Key, O_Value, json.GetAllocator());
|
||||
json.AddMember(T_Key, T_Value, json.GetAllocator());
|
||||
|
||||
json.Accept(writer);
|
||||
if (buffer.GetSize() > 240) {
|
||||
std::cout << "ERROR: Response info is too long." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(ResponseInfo, buffer.GetString(), buffer.GetSize());
|
||||
|
||||
std::cout << "Response Info:" << std::endl;
|
||||
std::cout << ResponseInfo << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
ResponseCode.resize(256);
|
||||
|
||||
if (!cipher->Encrypt<RSACipher::KeyType::PrivateKey>(ResponseInfo,
|
||||
strlen(ResponseInfo),
|
||||
ResponseCode.data(),
|
||||
RSA_PKCS1_PADDING)) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "ERROR: Encrypt<RSACipher::KeyType::PrivateKey> fails." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
ResponseCode_b64 = Helper::Base64Encode(ResponseCode);
|
||||
if (ResponseCode_b64.empty()) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "Base64Encode fails." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "License:" << std::endl;
|
||||
std::cout << ResponseCode_b64 << std::endl;
|
||||
}
|
||||
|
||||
if (flag == FLAG_BIN) {
|
||||
rapidjson::Value K_Key;
|
||||
rapidjson::Value K_Value;
|
||||
HANDLE hFile = INVALID_HANDLE_VALUE;
|
||||
DWORD NumberOfBytesWritten;
|
||||
|
||||
json.Parse("{}");
|
||||
|
||||
K_Key.SetString("K", 1);
|
||||
K_Value.SetString(keygen.GetKey().c_str(), keygen.GetKey().size());
|
||||
N_Key.SetString("N", 1);
|
||||
N_Value.SetString(username.c_str(), username.length());
|
||||
O_Key.SetString("O", 1);
|
||||
O_Value.SetString(organization.c_str(), organization.length());
|
||||
T_Key.SetString("T", 1);
|
||||
T_Value.SetUint(std::time(nullptr));
|
||||
|
||||
json.AddMember(K_Key, K_Value, json.GetAllocator());
|
||||
json.AddMember(N_Key, N_Value, json.GetAllocator());
|
||||
json.AddMember(O_Key, O_Value, json.GetAllocator());
|
||||
json.AddMember(T_Key, T_Value, json.GetAllocator());
|
||||
|
||||
json.Accept(writer);
|
||||
if (buffer.GetSize() > 240) {
|
||||
std::cout << "ERROR: Response info is too long." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(ResponseInfo, buffer.GetString(), buffer.GetSize());
|
||||
|
||||
std::cout << "Response Info:" << std::endl;
|
||||
std::cout << ResponseInfo << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
ResponseCode.resize(256);
|
||||
|
||||
if (!cipher->Encrypt<RSACipher::KeyType::PrivateKey>(ResponseInfo,
|
||||
strlen(ResponseInfo),
|
||||
ResponseCode.data(),
|
||||
RSA_PKCS1_PADDING)) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "ERROR: Encrypt<RSACipher::KeyType::PrivateKey> fails." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
hFile = CreateFile(TEXT("license_file"),
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
0,
|
||||
nullptr,
|
||||
CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
DWORD dwLastError = GetLastError();
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "ERROR: CreateFile fails. CODE: " << dwLastError << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!WriteFile(hFile, ResponseCode.data(), ResponseCode.size(), &NumberOfBytesWritten, nullptr)) {
|
||||
DWORD dwLastError = GetLastError();
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "ERROR: WriteFile fails. CODE: " << dwLastError << std::endl;
|
||||
CloseHandle(hFile);
|
||||
return;
|
||||
}
|
||||
|
||||
CloseHandle(hFile);
|
||||
|
||||
std::cout << "license_file has been generated." << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
return aCipher;
|
||||
}
|
||||
|
||||
bool GenerateKey(int bits, unsigned long long e = RSA_F4) {
|
||||
bool GenerateKey(int bits, unsigned int e = RSA_F4) {
|
||||
bool bSuccess = false;
|
||||
BIGNUM* bn_e = nullptr;
|
||||
|
||||
|
||||
@@ -1,460 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <ctime>
|
||||
|
||||
#include <tchar.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "NavicatKeygen.hpp"
|
||||
|
||||
#include <rapidjson/document.h>
|
||||
#include <rapidjson/writer.h>
|
||||
#include <rapidjson/stringbuffer.h>
|
||||
|
||||
bool ConvertToUTF8(LPCSTR from, std::string& to) {
|
||||
bool bSuccess = false;
|
||||
int len = 0;
|
||||
LPWSTR lpUnicodeString = nullptr;
|
||||
|
||||
len = MultiByteToWideChar(CP_ACP, NULL, from, -1, NULL, 0);
|
||||
if (len == 0)
|
||||
goto ON_ConvertToUTF8_0_ERROR;
|
||||
|
||||
lpUnicodeString = reinterpret_cast<LPWSTR>(HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
len * sizeof(WCHAR)));
|
||||
if (lpUnicodeString == nullptr)
|
||||
goto ON_ConvertToUTF8_0_ERROR;
|
||||
|
||||
if (!MultiByteToWideChar(CP_ACP, NULL, from, -1, lpUnicodeString, len))
|
||||
goto ON_ConvertToUTF8_0_ERROR;
|
||||
|
||||
len = WideCharToMultiByte(CP_UTF8, NULL, lpUnicodeString, -1, NULL, 0, NULL, NULL);
|
||||
if (len == 0)
|
||||
goto ON_ConvertToUTF8_0_ERROR;
|
||||
|
||||
to.resize(len);
|
||||
if (!WideCharToMultiByte(CP_UTF8, NULL, lpUnicodeString, -1, to.data(), len, NULL, NULL))
|
||||
goto ON_ConvertToUTF8_0_ERROR;
|
||||
|
||||
while (to.back() == 0)
|
||||
to.pop_back();
|
||||
|
||||
bSuccess = true;
|
||||
|
||||
ON_ConvertToUTF8_0_ERROR:
|
||||
if (lpUnicodeString)
|
||||
HeapFree(GetProcessHeap(), NULL, lpUnicodeString);
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
bool ConvertToUTF8(LPCWSTR from, std::string& to) {
|
||||
bool bSuccess = false;
|
||||
int len = 0;
|
||||
|
||||
len = WideCharToMultiByte(CP_UTF8, NULL, from, -1, NULL, 0, NULL, NULL);
|
||||
if (len == 0)
|
||||
goto ON_ConvertToUTF8_1_ERROR;
|
||||
|
||||
to.resize(len);
|
||||
if (!WideCharToMultiByte(CP_UTF8, NULL, from, -1, to.data(), len, NULL, NULL))
|
||||
goto ON_ConvertToUTF8_1_ERROR;
|
||||
|
||||
while (to.back() == 0)
|
||||
to.pop_back();
|
||||
|
||||
bSuccess = true;
|
||||
|
||||
ON_ConvertToUTF8_1_ERROR:
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
bool ConvertToUTF8(std::string& str) {
|
||||
bool bSuccess = false;
|
||||
|
||||
std::string temp;
|
||||
bSuccess = ConvertToUTF8(str.c_str(), temp);
|
||||
if (!bSuccess)
|
||||
return false;
|
||||
|
||||
str = temp;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string Base64Encode(const std::vector<uint8_t>& bytes) {
|
||||
std::string Result;
|
||||
DWORD pcchString = 0;
|
||||
|
||||
if (bytes.empty())
|
||||
return Result;
|
||||
|
||||
CryptBinaryToStringA(bytes.data(),
|
||||
bytes.size(),
|
||||
CRYPT_STRING_BASE64,
|
||||
NULL,
|
||||
&pcchString);
|
||||
if (pcchString == 0)
|
||||
return Result;
|
||||
|
||||
Result.resize(pcchString + 1);
|
||||
|
||||
if (!CryptBinaryToStringA(bytes.data(),
|
||||
bytes.size(),
|
||||
CRYPT_STRING_BASE64,
|
||||
Result.data(),
|
||||
&pcchString))
|
||||
Result.clear();
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> Base64Decode(std::string& str) {
|
||||
std::vector<uint8_t> Result;
|
||||
DWORD pcbBinary = 0;
|
||||
|
||||
if (str.empty())
|
||||
return Result;
|
||||
|
||||
CryptStringToBinaryA(str.c_str(),
|
||||
NULL,
|
||||
CRYPT_STRING_BASE64,
|
||||
NULL,
|
||||
&pcbBinary,
|
||||
NULL,
|
||||
NULL);
|
||||
if (pcbBinary == 0)
|
||||
return Result;
|
||||
|
||||
Result.resize(pcbBinary);
|
||||
|
||||
if (!CryptStringToBinaryA(str.c_str(),
|
||||
NULL,
|
||||
CRYPT_STRING_BASE64,
|
||||
Result.data(),
|
||||
&pcbBinary,
|
||||
NULL,
|
||||
NULL))
|
||||
Result.clear();
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
void help() {
|
||||
std::cout << "Usage:" << std::endl;
|
||||
std::cout << " navicat-keygen.exe <RSA-2048 PrivateKey(PEM file)>" << std::endl;
|
||||
}
|
||||
|
||||
bool GatherInformation(NavicatKeygen::Product& product,
|
||||
NavicatKeygen::Language& language,
|
||||
uint8_t& version) {
|
||||
int index = -1;
|
||||
std::string temp;
|
||||
|
||||
std::cout << "Select Navicat product:" << std::endl
|
||||
<< "0. DataModeler" << std::endl
|
||||
<< "1. Premium" << std::endl
|
||||
<< "2. MySQL" << std::endl
|
||||
<< "3. PostgreSQL" << std::endl
|
||||
<< "4. Oracle" << std::endl
|
||||
<< "5. SQLServer" << std::endl
|
||||
<< "6. SQLite" << std::endl
|
||||
<< "7. MariaDB" << std::endl
|
||||
<< "8. MongoDB" << std::endl
|
||||
<< "9. ReportViewer" << std::endl
|
||||
<< std::endl;
|
||||
|
||||
while (true) {
|
||||
std::cout << "(input index)> ";
|
||||
if (!std::getline(std::cin, temp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
index = std::stoi(temp);
|
||||
switch (index) {
|
||||
case 0:
|
||||
product = NavicatKeygen::Product::DataModeler;
|
||||
break;
|
||||
case 1:
|
||||
product = NavicatKeygen::Product::Premium;
|
||||
break;
|
||||
case 2:
|
||||
product = NavicatKeygen::Product::MySQL;
|
||||
break;
|
||||
case 3:
|
||||
product = NavicatKeygen::Product::PostgreSQL;
|
||||
break;
|
||||
case 4:
|
||||
product = NavicatKeygen::Product::Oracle;
|
||||
break;
|
||||
case 5:
|
||||
product = NavicatKeygen::Product::SQLServer;
|
||||
break;
|
||||
case 6:
|
||||
product = NavicatKeygen::Product::SQLite;
|
||||
break;
|
||||
case 7:
|
||||
product = NavicatKeygen::Product::MariaDB;
|
||||
break;
|
||||
case 8:
|
||||
product = NavicatKeygen::Product::MongoDB;
|
||||
break;
|
||||
case 9:
|
||||
product = NavicatKeygen::Product::ReportViewer;
|
||||
break;
|
||||
default:
|
||||
throw std::invalid_argument("Invalid index");
|
||||
}
|
||||
break;
|
||||
} catch (...) {
|
||||
std::cout << "Invalid index." << std::endl;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
std::cout << "Select product language:" << std::endl
|
||||
<< "0. English" << std::endl
|
||||
<< "1. Simplified Chinese" << std::endl
|
||||
<< "2. Traditional Chinese" << std::endl
|
||||
<< "3. Japanese" << std::endl
|
||||
<< "4. Polish" << std::endl
|
||||
<< "5. Spanish" << std::endl
|
||||
<< "6. French" << std::endl
|
||||
<< "7. German" << std::endl
|
||||
<< "8. Korean" << std::endl
|
||||
<< "9. Russian" << std::endl
|
||||
<< "10. Portuguese" << std::endl
|
||||
<< std::endl;
|
||||
|
||||
while (true) {
|
||||
std::cout << "(input index)> ";
|
||||
if (!std::getline(std::cin, temp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
index = std::stoi(temp);
|
||||
switch (index) {
|
||||
case 0:
|
||||
language = NavicatKeygen::Language::English;
|
||||
break;
|
||||
case 1:
|
||||
language = NavicatKeygen::Language::SimplifiedChinese;
|
||||
break;
|
||||
case 2:
|
||||
language = NavicatKeygen::Language::TraditionalChinese;
|
||||
break;
|
||||
case 3:
|
||||
language = NavicatKeygen::Language::Japanese;
|
||||
break;
|
||||
case 4:
|
||||
language = NavicatKeygen::Language::Polish;
|
||||
break;
|
||||
case 5:
|
||||
language = NavicatKeygen::Language::Spanish;
|
||||
break;
|
||||
case 6:
|
||||
language = NavicatKeygen::Language::French;
|
||||
break;
|
||||
case 7:
|
||||
language = NavicatKeygen::Language::German;
|
||||
break;
|
||||
case 8:
|
||||
language = NavicatKeygen::Language::Korean;
|
||||
break;
|
||||
case 9:
|
||||
language = NavicatKeygen::Language::Russian;
|
||||
break;
|
||||
case 10:
|
||||
language = NavicatKeygen::Language::Portuguese;
|
||||
break;
|
||||
default:
|
||||
throw std::invalid_argument("Invalid index");
|
||||
}
|
||||
break;
|
||||
} catch (...) {
|
||||
std::cout << "Invalid index." << std::endl;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
while (true) {
|
||||
std::cout << "(input major version number)> ";
|
||||
if (!std::getline(std::cin, temp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
version = std::stoi(temp);
|
||||
break;
|
||||
} catch (...) {
|
||||
std::cout << "Invalid index." << std::endl;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
int _tmain(int argc, LPTSTR argv[]) {
|
||||
if (argc != 2) {
|
||||
help();
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string RSAPrivateKeyPath;
|
||||
RSACipher* cipher = nullptr;
|
||||
std::string RequestCode_b64;
|
||||
std::string ResponseCode_b64;
|
||||
std::vector<uint8_t> RequestCode;
|
||||
std::vector<uint8_t> ResponseCode;
|
||||
char RequestInfo[256] = {};
|
||||
char ResponseInfo[256] = {};
|
||||
|
||||
rapidjson::Document json;
|
||||
|
||||
NavicatKeygen keygen;
|
||||
NavicatKeygen::Product product;
|
||||
NavicatKeygen::Language language;
|
||||
uint8_t version = 0;
|
||||
std::string username;
|
||||
std::string organization;
|
||||
|
||||
cipher = RSACipher::Create();
|
||||
if (cipher == nullptr) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "Failed to create RSACipher." << std::endl;
|
||||
goto ON_tmain_ERROR;
|
||||
}
|
||||
|
||||
if (!ConvertToUTF8(argv[1], RSAPrivateKeyPath)) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "ConvertToUTF8 fails." << std::endl;
|
||||
goto ON_tmain_ERROR;
|
||||
}
|
||||
|
||||
if (!cipher->ImportKeyFromFile<RSACipher::KeyType::PrivateKey>(RSAPrivateKeyPath)) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "ImportKeyFromFile fails." << std::endl;
|
||||
goto ON_tmain_ERROR;
|
||||
}
|
||||
|
||||
GatherInformation(product, language, version);
|
||||
|
||||
keygen.Generate(version, language, product);
|
||||
std::cout << "Serial number:" << std::endl;
|
||||
std::cout << keygen.GetFormatedKey() << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "Your name: ";
|
||||
if (!std::getline(std::cin, username))
|
||||
goto ON_tmain_ERROR;
|
||||
if (!ConvertToUTF8(username)) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "ConvertToUTF8 fails." << std::endl;
|
||||
goto ON_tmain_ERROR;
|
||||
}
|
||||
|
||||
std::cout << "Your organization: ";
|
||||
if (!std::getline(std::cin, organization))
|
||||
goto ON_tmain_ERROR;
|
||||
if (!ConvertToUTF8(organization)) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "ConvertToUTF8 fails." << std::endl;
|
||||
goto ON_tmain_ERROR;
|
||||
}
|
||||
|
||||
std::cout << "Input request code (in Base64), input empty line to end:" << std::endl;
|
||||
while (true) {
|
||||
std::string temp;
|
||||
if (!std::getline(std::cin, temp))
|
||||
goto ON_tmain_ERROR;
|
||||
|
||||
if (temp.empty())
|
||||
break;
|
||||
|
||||
RequestCode_b64 += temp;
|
||||
}
|
||||
|
||||
RequestCode = Base64Decode(RequestCode_b64);
|
||||
if (RequestCode.empty()) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "Base64Decode fails." << std::endl;
|
||||
goto ON_tmain_ERROR;
|
||||
}
|
||||
|
||||
if (!cipher->Decrypt(RequestCode.data(),
|
||||
RequestCode.size(),
|
||||
RequestInfo,
|
||||
RSA_PKCS1_PADDING)) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "Decrypt<RSACipher::KeyType::PrivateKey> fails." << std::endl;
|
||||
goto ON_tmain_ERROR;
|
||||
}
|
||||
|
||||
std::cout << "Request Info:" << std::endl;
|
||||
std::cout << RequestInfo << std::endl << std::endl;
|
||||
|
||||
json.Parse(RequestInfo);
|
||||
json.RemoveMember("P");
|
||||
|
||||
{
|
||||
rapidjson::Value N_Key;
|
||||
rapidjson::Value N_Value;
|
||||
rapidjson::Value O_Key;
|
||||
rapidjson::Value O_Value;
|
||||
rapidjson::Value T_Key;
|
||||
rapidjson::Value T_Value;
|
||||
rapidjson::StringBuffer buffer;
|
||||
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
|
||||
|
||||
N_Key.SetString("N", 1);
|
||||
N_Value.SetString(username.c_str(), username.length());
|
||||
O_Key.SetString("O", 1);
|
||||
O_Value.SetString(organization.c_str(), organization.length());
|
||||
T_Key.SetString("T", 1);
|
||||
T_Value.SetUint(std::time(nullptr));
|
||||
|
||||
json.AddMember(N_Key, N_Value, json.GetAllocator());
|
||||
json.AddMember(O_Key, O_Value, json.GetAllocator());
|
||||
json.AddMember(T_Key, T_Value, json.GetAllocator());
|
||||
|
||||
json.Accept(writer);
|
||||
if (buffer.GetSize() > 240) {
|
||||
std::cout << "Response info too long." << std::endl;
|
||||
goto ON_tmain_ERROR;
|
||||
}
|
||||
|
||||
memcpy(ResponseInfo, buffer.GetString(), buffer.GetSize());
|
||||
}
|
||||
|
||||
std::cout << "Response Info:" << std::endl;
|
||||
std::cout << ResponseInfo << std::endl << std::endl;
|
||||
|
||||
ResponseCode.resize(256);
|
||||
|
||||
if (!cipher->Encrypt<RSACipher::KeyType::PrivateKey>(ResponseInfo,
|
||||
strlen(ResponseInfo),
|
||||
ResponseCode.data(),
|
||||
RSA_PKCS1_PADDING)) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "Encrypt<RSACipher::KeyType::PrivateKey> fails." << std::endl;
|
||||
goto ON_tmain_ERROR;
|
||||
}
|
||||
|
||||
ResponseCode_b64 = Base64Encode(ResponseCode);
|
||||
if (ResponseCode_b64.empty()) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "Base64Encode fails." << std::endl;
|
||||
goto ON_tmain_ERROR;
|
||||
}
|
||||
|
||||
std::cout << "License:" << std::endl;
|
||||
std::cout << ResponseCode_b64 << std::endl;
|
||||
|
||||
ON_tmain_ERROR:
|
||||
if (cipher)
|
||||
delete cipher;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
#include <iostream>
|
||||
#include "RSACipher.hpp"
|
||||
|
||||
namespace Helper {
|
||||
bool ConvertToUTF8(std::string& str);
|
||||
}
|
||||
|
||||
#define MODE_SIMPLE 1
|
||||
#define MODE_ADVANCED 2
|
||||
#define FLAG_BIN 1
|
||||
#define FLAG_TEXT 2
|
||||
void Process(RSACipher* cipher, int mode, int flag);
|
||||
|
||||
void help() {
|
||||
std::cout << "Usage:" << std::endl;
|
||||
std::cout << " navicat-keygen.exe <-bin|-text> [-adv] <RSA-2048 PrivateKey(PEM file)>" << std::endl;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 3 && argc != 4) {
|
||||
help();
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string RSAPrivateKeyPath = argv[argc - 1];
|
||||
RSACipher* cipher = nullptr;
|
||||
|
||||
cipher = RSACipher::Create();
|
||||
if (cipher == nullptr) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "ERROR: Failed to create RSACipher." << std::endl;
|
||||
goto ON_tmain_ERROR;
|
||||
}
|
||||
|
||||
if (!Helper::ConvertToUTF8(RSAPrivateKeyPath)) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "ERROR: ConvertToUTF8 fails." << std::endl;
|
||||
goto ON_tmain_ERROR;
|
||||
}
|
||||
|
||||
if (!cipher->ImportKeyFromFile<RSACipher::KeyType::PrivateKey>(RSAPrivateKeyPath)) {
|
||||
std::cout << "@Function: " << __FUNCSIG__ << " LINE: " << __LINE__ << std::endl;
|
||||
std::cout << "ERROR: ImportKeyFromFile<RSACipher::KeyType::PrivateKey> fails." << std::endl;
|
||||
goto ON_tmain_ERROR;
|
||||
}
|
||||
|
||||
if (argc == 3) {
|
||||
if (_stricmp(argv[1], "-bin") == 0)
|
||||
Process(cipher, MODE_SIMPLE, FLAG_BIN);
|
||||
else if (_stricmp(argv[1], "-text") == 0)
|
||||
Process(cipher, MODE_SIMPLE, FLAG_TEXT);
|
||||
else
|
||||
help();
|
||||
}
|
||||
|
||||
if (argc == 4) {
|
||||
if (_stricmp(argv[1], "-bin") == 0)
|
||||
Process(cipher, MODE_ADVANCED, FLAG_BIN);
|
||||
else if (_stricmp(argv[1], "-text") == 0)
|
||||
Process(cipher, MODE_ADVANCED, FLAG_TEXT);
|
||||
else
|
||||
help();
|
||||
}
|
||||
|
||||
ON_tmain_ERROR:
|
||||
if (cipher)
|
||||
delete cipher;
|
||||
return 0;
|
||||
}
|
||||
@@ -166,7 +166,9 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="_tmain.cpp" />
|
||||
<ClCompile Include="Helper.cpp" />
|
||||
<ClCompile Include="Process.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="NavicatKeygen.hpp" />
|
||||
|
||||
@@ -15,7 +15,13 @@
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="_tmain.cpp">
|
||||
<ClCompile Include="Helper.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Process.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
// to avoid "AES_KEY" definaition conflict
|
||||
#include "NavicatCrypto/NavicatCrypto.hpp"
|
||||
|
||||
namespace patcher {
|
||||
|
||||
static Navicat11Crypto cipher("23970790", 8);
|
||||
|
||||
std::string EncryptPublicKey(const char* public_key, size_t len) {
|
||||
auto&& temp = cipher.EncryptString(public_key, len);
|
||||
return std::string(temp.begin(), temp.end());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
class Exception {
|
||||
private:
|
||||
const char* const _FileName;
|
||||
const int _NumberOfLine;
|
||||
const char* _CustomMessage;
|
||||
public:
|
||||
|
||||
Exception(const char* FileName, int Line, const char* Message) noexcept :
|
||||
_FileName(FileName),
|
||||
_NumberOfLine(Line),
|
||||
_CustomMessage(Message) {}
|
||||
|
||||
const char* SourceFile() const noexcept {
|
||||
return _FileName;
|
||||
}
|
||||
|
||||
int SourceLine() const noexcept {
|
||||
return _NumberOfLine;
|
||||
}
|
||||
|
||||
const char* CustomMessage() const noexcept {
|
||||
return _CustomMessage;
|
||||
}
|
||||
|
||||
virtual bool HasErrorCode() const noexcept {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual unsigned long ErrorCode() const noexcept {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual const char* ErrorString() const noexcept {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
#include "Exception.hpp"
|
||||
|
||||
#if defined(CAPSTONE_ENGINE_H) // if include <capstone/capstone.h>
|
||||
|
||||
class CapstoneError : public Exception {
|
||||
private:
|
||||
const cs_err _ErrorCode;
|
||||
public:
|
||||
CapstoneError(const char* FileName,
|
||||
int Line,
|
||||
cs_err Code,
|
||||
const char* Message) noexcept :
|
||||
Exception(FileName, Line, Message),
|
||||
_ErrorCode(Code) {}
|
||||
|
||||
virtual bool HasErrorCode() const noexcept override {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual unsigned long ErrorCode() const noexcept override {
|
||||
return _ErrorCode;
|
||||
}
|
||||
|
||||
virtual const char* ErrorString() const noexcept override {
|
||||
switch (_ErrorCode) {
|
||||
case CS_ERR_MEM:
|
||||
return "Out-Of-Memory error.";
|
||||
case CS_ERR_ARCH:
|
||||
return "Unsupported architecture.";
|
||||
case CS_ERR_HANDLE:
|
||||
return "Invalid handle.";
|
||||
case CS_ERR_CSH:
|
||||
return "Invalid csh argument.";
|
||||
case CS_ERR_MODE:
|
||||
return "Invalid/unsupported mode.";
|
||||
case CS_ERR_OPTION:
|
||||
return "Invalid/unsupported option.";
|
||||
case CS_ERR_DETAIL:
|
||||
return "Information is unavailable because detail option is OFF";
|
||||
case CS_ERR_MEMSETUP:
|
||||
return "Dynamic memory management uninitialized.";
|
||||
case CS_ERR_VERSION:
|
||||
return "Unsupported version (bindings).";
|
||||
case CS_ERR_DIET:
|
||||
return "Access irrelevant data in \"diet\" engine.";
|
||||
case CS_ERR_SKIPDATA:
|
||||
return "Access irrelevant data for \"data\" instruction in SKIPDATA mode.";
|
||||
case CS_ERR_X86_ATT:
|
||||
return "X86 AT&T syntax is unsupported (opt-out at compile time).";
|
||||
case CS_ERR_X86_INTEL:
|
||||
return "X86 Intel syntax is unsupported (opt-out at compile time).";
|
||||
case CS_ERR_X86_MASM:
|
||||
return "X86 Intel syntax is unsupported (opt-out at compile time).";
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
#include "Exception.hpp"
|
||||
|
||||
#if defined(HEADER_ERR_H) // if include <openssl/err.h>
|
||||
|
||||
class OpensslError : public Exception {
|
||||
private:
|
||||
const unsigned long _ErrorCode;
|
||||
public:
|
||||
|
||||
OpensslError(const char* FileName,
|
||||
int Line,
|
||||
unsigned long Code,
|
||||
const char* Message) noexcept :
|
||||
Exception(FileName, Line, Message),
|
||||
_ErrorCode(Code) {}
|
||||
|
||||
virtual bool HasErrorCode() const noexcept override {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual unsigned long ErrorCode() const noexcept override {
|
||||
return _ErrorCode;
|
||||
}
|
||||
|
||||
virtual const char* ErrorString() const noexcept override {
|
||||
return ERR_error_string(_ErrorCode, nullptr);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
#include "Exception.hpp"
|
||||
#include <system_error>
|
||||
|
||||
class SystemError : public Exception {
|
||||
private:
|
||||
const std::error_code _ErrorCode;
|
||||
const std::string _ErrorString;
|
||||
public:
|
||||
SystemError(const char* FileName,
|
||||
int Line,
|
||||
unsigned long Code,
|
||||
const char* Message) noexcept :
|
||||
Exception(FileName, Line, Message),
|
||||
_ErrorCode(Code, std::system_category()),
|
||||
_ErrorString(_ErrorCode.message()) {}
|
||||
|
||||
virtual bool HasErrorCode() const noexcept override {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual unsigned long ErrorCode() const noexcept override {
|
||||
return _ErrorCode.value();
|
||||
}
|
||||
|
||||
virtual const char* ErrorString() const noexcept override {
|
||||
return _ErrorString.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
|
||||
#include "ExceptionSystem.hpp"
|
||||
#include "ResourceGuardWin32.hpp"
|
||||
|
||||
#undef __BASE_FILE__
|
||||
#define __BASE_FILE__ "FileMapper.hpp"
|
||||
|
||||
#if defined(UNICODE) || defined(_UNICODE)
|
||||
using String = std::wstring;
|
||||
#else
|
||||
using String = std::string;
|
||||
#endif
|
||||
|
||||
class FileMapper {
|
||||
private:
|
||||
ResourceGuard<FileHandleTraits> _FileHandle;
|
||||
ResourceGuard<GenericHandleTraits> _FileMapHandle;
|
||||
ResourceGuard<MapViewTraits> _FileView;
|
||||
public:
|
||||
|
||||
static bool IsExist(const String&& FilePath) {
|
||||
DWORD dwAttr = GetFileAttributes(FilePath.c_str());
|
||||
if (dwAttr == INVALID_FILE_ATTRIBUTES) {
|
||||
if (GetLastError() == ERROR_FILE_NOT_FOUND)
|
||||
return false;
|
||||
else
|
||||
throw SystemError(__BASE_FILE__, __LINE__, GetLastError(),
|
||||
"GetFileAttributes fails.");
|
||||
} else {
|
||||
return (dwAttr & FILE_ATTRIBUTE_DIRECTORY) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename _Type>
|
||||
_Type* GetView() const noexcept {
|
||||
return reinterpret_cast<_Type*>(_FileView.GetHandle());
|
||||
}
|
||||
|
||||
void MapFile(const String& FileName) {
|
||||
ResourceGuard<FileHandleTraits> TempFileHandle;
|
||||
ResourceGuard<GenericHandleTraits> TempFileMapHandle;
|
||||
ResourceGuard<MapViewTraits> TempFileView;
|
||||
|
||||
TempFileHandle.TakeHoldOf(
|
||||
CreateFile(FileName.c_str(),
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL)
|
||||
);
|
||||
if (TempFileHandle.IsValid() == false)
|
||||
throw SystemError(__BASE_FILE__, __LINE__, GetLastError(),
|
||||
"CreateFile fails.");
|
||||
|
||||
TempFileMapHandle.TakeHoldOf(
|
||||
CreateFileMapping(TempFileHandle,
|
||||
NULL,
|
||||
PAGE_READWRITE,
|
||||
0,
|
||||
0,
|
||||
NULL)
|
||||
);
|
||||
if (TempFileMapHandle.IsValid() == false)
|
||||
throw SystemError(__BASE_FILE__, __LINE__, GetLastError(),
|
||||
"CreateFileMapping fails.");
|
||||
|
||||
TempFileView.TakeHoldOf(
|
||||
MapViewOfFile(TempFileMapHandle,
|
||||
FILE_MAP_READ | FILE_MAP_WRITE,
|
||||
0,
|
||||
0,
|
||||
0)
|
||||
);
|
||||
if (TempFileView.IsValid() == false)
|
||||
throw SystemError(__BASE_FILE__, __LINE__, GetLastError(),
|
||||
"MapViewOfFile fails.");
|
||||
|
||||
_FileView.Release();
|
||||
_FileView = std::move(TempFileView);
|
||||
_FileMapHandle.Release();
|
||||
_FileMapHandle = std::move(TempFileMapHandle);
|
||||
_FileHandle.Release();
|
||||
_FileHandle = std::move(TempFileHandle);
|
||||
}
|
||||
|
||||
void Release() {
|
||||
_FileView.Release();
|
||||
_FileMapHandle.Release();
|
||||
_FileHandle.Release();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,211 @@
|
||||
#include "Helper.hpp"
|
||||
#include <tchar.h>
|
||||
#include "ExceptionSystem.hpp"
|
||||
#include "ResourceGuard.hpp"
|
||||
|
||||
#undef __BASE_FILE__
|
||||
#define __BASE_FILE__ "Helper.cpp"
|
||||
|
||||
namespace Helper {
|
||||
|
||||
Navicat11Crypto NavicatCipher("23970790", 8);
|
||||
|
||||
std::string ConvertToUTF8(PCSTR From, DWORD CodePage) {
|
||||
std::string result;
|
||||
int RequiredLength = 0;
|
||||
ResourceGuard<CppDynamicArrayTraits<WCHAR>> pszUnicodeString;
|
||||
|
||||
RequiredLength = MultiByteToWideChar(CP_ACP,
|
||||
NULL,
|
||||
From,
|
||||
-1,
|
||||
nullptr,
|
||||
0);
|
||||
if (RequiredLength == 0)
|
||||
throw SystemError(__BASE_FILE__, __LINE__, GetLastError(),
|
||||
"MultiByteToWideChar fails.");
|
||||
|
||||
pszUnicodeString.TakeHoldOf(new WCHAR[RequiredLength]());
|
||||
|
||||
if (!MultiByteToWideChar(CP_ACP,
|
||||
NULL,
|
||||
From,
|
||||
-1,
|
||||
pszUnicodeString,
|
||||
RequiredLength))
|
||||
throw SystemError(__BASE_FILE__, __LINE__, GetLastError(),
|
||||
"MultiByteToWideChar fails.");
|
||||
|
||||
RequiredLength = WideCharToMultiByte(CP_UTF8,
|
||||
NULL,
|
||||
pszUnicodeString,
|
||||
-1,
|
||||
nullptr,
|
||||
0,
|
||||
nullptr,
|
||||
nullptr);
|
||||
if (RequiredLength == 0)
|
||||
throw SystemError(__BASE_FILE__, __LINE__, GetLastError(),
|
||||
"WideCharToMultiByte fails.");
|
||||
|
||||
result.resize(RequiredLength);
|
||||
|
||||
if (!WideCharToMultiByte(CP_UTF8,
|
||||
NULL,
|
||||
pszUnicodeString,
|
||||
-1,
|
||||
result.data(),
|
||||
RequiredLength,
|
||||
nullptr,
|
||||
nullptr))
|
||||
throw SystemError(__BASE_FILE__, __LINE__, GetLastError(),
|
||||
"WideCharToMultiByte fails.");
|
||||
|
||||
while (result.back() == 0)
|
||||
result.pop_back();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string ConvertToUTF8(PCWSTR From) {
|
||||
std::string result;
|
||||
int RequiredLength = 0;
|
||||
|
||||
RequiredLength = WideCharToMultiByte(CP_UTF8,
|
||||
NULL,
|
||||
From,
|
||||
-1,
|
||||
nullptr,
|
||||
0,
|
||||
nullptr,
|
||||
nullptr);
|
||||
if (RequiredLength == 0)
|
||||
throw SystemError(__BASE_FILE__, __LINE__, GetLastError(),
|
||||
"WideCharToMultiByte fails.");
|
||||
|
||||
result.resize(RequiredLength);
|
||||
|
||||
if (!WideCharToMultiByte(CP_UTF8,
|
||||
NULL,
|
||||
From,
|
||||
-1,
|
||||
result.data(),
|
||||
RequiredLength,
|
||||
nullptr,
|
||||
nullptr))
|
||||
throw SystemError(__BASE_FILE__, __LINE__, GetLastError(),
|
||||
"WideCharToMultiByte fails.");
|
||||
|
||||
while (result.back() == 0)
|
||||
result.pop_back();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// read byte(s) at address `p` as _Type to `out`
|
||||
// succeed if return true, otherwise return false
|
||||
//
|
||||
template<typename _Type>
|
||||
static __forceinline bool ProbeForRead(const void* p, void* out) {
|
||||
__try {
|
||||
*reinterpret_cast<_Type*>(out) = *reinterpret_cast<const _Type*>(p);
|
||||
return true;
|
||||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Print memory data in [from, to) at least
|
||||
// If `base` is not nullptr, print address as offset. Otherwise, as absolute address.
|
||||
// NOTICE:
|
||||
// `base` must <= `from`
|
||||
//
|
||||
void PrintMemory(const void* from, const void* to, const void* base) {
|
||||
const uint8_t* start = reinterpret_cast<const uint8_t*>(from);
|
||||
const uint8_t* end = reinterpret_cast<const uint8_t*>(to);
|
||||
const uint8_t* base_ptr = reinterpret_cast<const uint8_t*>(base);
|
||||
|
||||
if (start >= end)
|
||||
return;
|
||||
|
||||
while (reinterpret_cast<uintptr_t>(start) % 16)
|
||||
start--;
|
||||
|
||||
while (reinterpret_cast<uintptr_t>(start) % 16)
|
||||
end++;
|
||||
|
||||
while (start < end) {
|
||||
uint16_t value[16] = {};
|
||||
|
||||
if (base_ptr)
|
||||
_tprintf(TEXT("+0x%p "), reinterpret_cast<const void*>(start - base_ptr));
|
||||
else
|
||||
_tprintf(TEXT("0x%p "), start);
|
||||
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
if (ProbeForRead<uint8_t>(start + i, value + i)) {
|
||||
_tprintf(TEXT("%02x "), value[i]);
|
||||
} else {
|
||||
value[i] = -1;
|
||||
_tprintf(TEXT("?? "));
|
||||
}
|
||||
}
|
||||
|
||||
_tprintf(TEXT(" "));
|
||||
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
if (value[i] < 0x20) {
|
||||
_tprintf(TEXT("."));
|
||||
} else if (value[i] > 0x7e) {
|
||||
_tprintf(TEXT("."));
|
||||
} else {
|
||||
_tprintf(TEXT("%c"), value[i]);
|
||||
}
|
||||
}
|
||||
|
||||
_tprintf(TEXT("\n"));
|
||||
|
||||
start += 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
void PrintSomeBytes(const void* p, size_t s) {
|
||||
const uint8_t* byte_ptr = reinterpret_cast<const uint8_t*>(p);
|
||||
|
||||
if (s == 0)
|
||||
return;
|
||||
|
||||
if (s == 1) {
|
||||
_tprintf_s(TEXT("%02X"), byte_ptr[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
s -= 1;
|
||||
for (size_t i = 0; i < s; ++i)
|
||||
_tprintf_s(TEXT("%02X "), byte_ptr[i]);
|
||||
|
||||
_tprintf_s(TEXT("%02X"), byte_ptr[s]);
|
||||
}
|
||||
|
||||
bool IsPrintable(const uint8_t* p, size_t s) {
|
||||
for (size_t i = 0; i < s; ++i)
|
||||
if (isprint(p[i]) == false)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ReplaceSubString(std::string& Str,
|
||||
const std::string& OldSubStr,
|
||||
const std::string& NewSubStr) {
|
||||
std::string::size_type pos = 0;
|
||||
std::string::size_type srclen = OldSubStr.size();
|
||||
std::string::size_type dstlen = NewSubStr.size();
|
||||
|
||||
while ((pos = Str.find(OldSubStr, pos)) != std::string::npos) {
|
||||
Str.replace(pos, srclen, NewSubStr);
|
||||
pos += dstlen;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
#include <sys/types.h>
|
||||
#include "NavicatCrypto.hpp"
|
||||
|
||||
#undef __BASE_FILE__
|
||||
#define __BASE_FILE__ "Helper.hpp"
|
||||
|
||||
namespace Helper {
|
||||
|
||||
extern Navicat11Crypto NavicatCipher;
|
||||
|
||||
//
|
||||
// Print memory data in [from, to) at least
|
||||
// If `base` is not nullptr, print address as offset. Otherwise, as absolute address.
|
||||
// NOTICE:
|
||||
// `base` must <= `from`
|
||||
//
|
||||
void PrintMemory(const void* from, const void* to, const void* base = nullptr);
|
||||
void PrintSomeBytes(const void* p, size_t s);
|
||||
|
||||
template<typename _Type, bool _Ascending = true>
|
||||
void QuickSort(_Type* pArray, off_t begin, off_t end) {
|
||||
if (end - begin <= 1)
|
||||
return;
|
||||
|
||||
off_t i = begin;
|
||||
off_t j = end - 1;
|
||||
_Type seperator = static_cast<_Type&&>(pArray[begin]);
|
||||
|
||||
while (i < j) {
|
||||
if (_Ascending) {
|
||||
while (i < j && seperator <= pArray[j])
|
||||
--j;
|
||||
|
||||
if (i < j)
|
||||
pArray[i++] = static_cast<_Type&&>(pArray[j]);
|
||||
|
||||
while (i < j && pArray[i] <= seperator)
|
||||
++i;
|
||||
|
||||
if (i < j)
|
||||
pArray[j--] = static_cast<_Type&&>(pArray[i]);
|
||||
} else {
|
||||
while (i < j && seperator >= pArray[j])
|
||||
--j;
|
||||
|
||||
if (i < j)
|
||||
pArray[i++] = static_cast<_Type&&>(pArray[j]);
|
||||
|
||||
while (i < j && pArray[i] >= seperator)
|
||||
++i;
|
||||
|
||||
if (i < j)
|
||||
pArray[j--] = static_cast<_Type&&>(pArray[i]);
|
||||
}
|
||||
}
|
||||
|
||||
pArray[i] = static_cast<_Type&&>(seperator);
|
||||
QuickSort<_Type, _Ascending>(pArray, begin, i);
|
||||
QuickSort<_Type, _Ascending>(pArray, i + 1, end);
|
||||
}
|
||||
|
||||
std::string ConvertToUTF8(PCSTR From, DWORD CodePage = CP_ACP);
|
||||
std::string ConvertToUTF8(PCWSTR From);
|
||||
|
||||
bool IsPrintable(const uint8_t* p, size_t s);
|
||||
|
||||
void ReplaceSubString(std::string& Str,
|
||||
const std::string& OldSubStr,
|
||||
const std::string& NewSubStr);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,246 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
#include <map>
|
||||
|
||||
#undef __BASE_FILE__
|
||||
#define __BASE_FILE__ "ImageInterpreter.hpp"
|
||||
|
||||
class ImageInterpreter {
|
||||
private:
|
||||
PVOID _PtrToImageBase;
|
||||
PIMAGE_NT_HEADERS _PtrToNTHeaders;
|
||||
PIMAGE_SECTION_HEADER _PtrToSectionHeaderTable;
|
||||
std::map<uint64_t, size_t> _SectionNameTable;
|
||||
std::map<uintptr_t, size_t> _SectionMapAddressTable;
|
||||
std::map<uintptr_t, size_t> _RelocationAddressTable;
|
||||
public:
|
||||
|
||||
bool ParseImage(const PVOID PtrToImageBase, bool DisableRelocParsing = false) {
|
||||
if (PtrToImageBase == nullptr)
|
||||
return false;
|
||||
|
||||
PIMAGE_DOS_HEADER PtrToDosHeader =
|
||||
reinterpret_cast<PIMAGE_DOS_HEADER>(PtrToImageBase);
|
||||
if (PtrToDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
|
||||
return false;
|
||||
|
||||
PIMAGE_NT_HEADERS PtrToNtHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>(
|
||||
reinterpret_cast<uint8_t*>(PtrToImageBase) +
|
||||
PtrToDosHeader->e_lfanew
|
||||
);
|
||||
if (PtrToNtHeaders->Signature != IMAGE_NT_SIGNATURE)
|
||||
return false;
|
||||
if (PtrToNtHeaders->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)
|
||||
return false;
|
||||
#if defined(_M_AMD64)
|
||||
if (PtrToNtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64)
|
||||
return false;
|
||||
#elif defined(_M_IX86)
|
||||
if (PtrToNtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_I386)
|
||||
return false;
|
||||
#else
|
||||
#error "Unsupported architecture."
|
||||
#endif
|
||||
|
||||
PIMAGE_SECTION_HEADER PtrToSectionHeaderTable =
|
||||
reinterpret_cast<PIMAGE_SECTION_HEADER>(
|
||||
reinterpret_cast<char*>(&PtrToNtHeaders->OptionalHeader) +
|
||||
PtrToNtHeaders->FileHeader.SizeOfOptionalHeader
|
||||
);
|
||||
|
||||
std::map<uint64_t, size_t> SectionNameTable;
|
||||
std::map<uintptr_t, size_t> SectioMapAddressTable;
|
||||
std::map<uintptr_t, size_t> RelocationAddressTable;
|
||||
|
||||
for (WORD i = 0; i < PtrToNtHeaders->FileHeader.NumberOfSections; ++i) {
|
||||
uint64_t SectionName =
|
||||
*reinterpret_cast<uint64_t*>(PtrToSectionHeaderTable[i].Name);
|
||||
if (SectionNameTable.find(SectionName) != SectionNameTable.end())
|
||||
continue;
|
||||
SectionNameTable[SectionName] = i;
|
||||
|
||||
|
||||
uintptr_t SectionMapAddress =
|
||||
PtrToSectionHeaderTable[i].VirtualAddress;
|
||||
SectioMapAddressTable[SectionMapAddress] = i;
|
||||
}
|
||||
|
||||
if (DisableRelocParsing == false &&
|
||||
PtrToNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0) {
|
||||
DWORD RelocTableRva =
|
||||
PtrToNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
|
||||
PIMAGE_BASE_RELOCATION PtrToRelocTable = nullptr;
|
||||
|
||||
{
|
||||
auto v = SectioMapAddressTable.lower_bound(RelocTableRva);
|
||||
|
||||
if (v != SectioMapAddressTable.end()) {
|
||||
if (v->first != RelocTableRva) {
|
||||
if (v != SectioMapAddressTable.begin()) {
|
||||
--v;
|
||||
PtrToRelocTable = reinterpret_cast<PIMAGE_BASE_RELOCATION>(
|
||||
reinterpret_cast<uint8_t*>(PtrToImageBase) +
|
||||
PtrToSectionHeaderTable[v->second].PointerToRawData
|
||||
);
|
||||
}
|
||||
} else {
|
||||
PtrToRelocTable = reinterpret_cast<PIMAGE_BASE_RELOCATION>(
|
||||
reinterpret_cast<uint8_t*>(PtrToImageBase) +
|
||||
PtrToSectionHeaderTable[v->second].PointerToRawData
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (PtrToRelocTable != nullptr && PtrToRelocTable->VirtualAddress != 0) {
|
||||
DWORD Rva = PtrToRelocTable->VirtualAddress;
|
||||
PWORD RelocItems = reinterpret_cast<PWORD>(PtrToRelocTable + 1);
|
||||
DWORD RelocItemsCount = (PtrToRelocTable->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
|
||||
for (DWORD i = 0; i < RelocItemsCount; ++i) {
|
||||
int RelocType = RelocItems[i] >> 12;
|
||||
switch (RelocType) {
|
||||
case IMAGE_REL_BASED_ABSOLUTE:
|
||||
break;
|
||||
case IMAGE_REL_BASED_HIGH:
|
||||
case IMAGE_REL_BASED_LOW:
|
||||
case IMAGE_REL_BASED_HIGHADJ:
|
||||
RelocationAddressTable[Rva + (RelocItems[i] & 0x0fff)] = 2;
|
||||
break;
|
||||
case IMAGE_REL_BASED_HIGHLOW:
|
||||
RelocationAddressTable[Rva + (RelocItems[i] & 0x0fff)] = 4;
|
||||
break;
|
||||
#if defined(IMAGE_REL_BASED_DIR64)
|
||||
case IMAGE_REL_BASED_DIR64:
|
||||
RelocationAddressTable[Rva + (RelocItems[i] & 0x0fff)] = 8;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
PtrToRelocTable = reinterpret_cast<PIMAGE_BASE_RELOCATION>(
|
||||
&RelocItems[RelocItemsCount]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
_PtrToImageBase = PtrToImageBase;
|
||||
_PtrToNTHeaders = PtrToNtHeaders;
|
||||
_PtrToSectionHeaderTable = PtrToSectionHeaderTable;
|
||||
_SectionNameTable = std::move(SectionNameTable);
|
||||
_SectionMapAddressTable = std::move(SectioMapAddressTable);
|
||||
_RelocationAddressTable = std::move(RelocationAddressTable);
|
||||
return true;
|
||||
}
|
||||
|
||||
ImageInterpreter() :
|
||||
_PtrToImageBase(nullptr),
|
||||
_PtrToNTHeaders(nullptr),
|
||||
_PtrToSectionHeaderTable(nullptr) {}
|
||||
|
||||
template<typename __Type>
|
||||
__Type* GetImageBaseView() const {
|
||||
return reinterpret_cast<__Type*>(_PtrToImageBase);
|
||||
}
|
||||
|
||||
PIMAGE_NT_HEADERS GetImageNTHeaders() const {
|
||||
return _PtrToNTHeaders;
|
||||
}
|
||||
|
||||
PIMAGE_SECTION_HEADER GetSectionHeaderTable() const {
|
||||
return _PtrToSectionHeaderTable;
|
||||
}
|
||||
|
||||
PIMAGE_SECTION_HEADER GetSectionHeader(const char* SectionName) const {
|
||||
uint64_t NameValue = 0;
|
||||
|
||||
for (int i = 0; i < sizeof(NameValue) && SectionName[i]; ++i)
|
||||
reinterpret_cast<char*>(&NameValue)[i] = SectionName[i];
|
||||
|
||||
auto v = _SectionNameTable.find(NameValue);
|
||||
|
||||
if (v == _SectionNameTable.end())
|
||||
return nullptr;
|
||||
else
|
||||
return &_PtrToSectionHeaderTable[v->second];
|
||||
}
|
||||
|
||||
PIMAGE_SECTION_HEADER GetSectionHeader(uintptr_t Rva) const {
|
||||
auto v = _SectionMapAddressTable.lower_bound(Rva);
|
||||
|
||||
if (v == _SectionMapAddressTable.end())
|
||||
return nullptr;
|
||||
|
||||
if (v->first != Rva) {
|
||||
if (v == _SectionMapAddressTable.begin())
|
||||
return nullptr;
|
||||
--v;
|
||||
return &_PtrToSectionHeaderTable[v->second];
|
||||
} else {
|
||||
return &_PtrToSectionHeaderTable[v->second];
|
||||
}
|
||||
}
|
||||
|
||||
template<typename __Type>
|
||||
__Type* GetSectionView(const char* SectionName) const {
|
||||
auto PtrToSectionHeader = GetSectionHeader(SectionName);
|
||||
|
||||
if (PtrToSectionHeader == nullptr)
|
||||
return nullptr;
|
||||
|
||||
return reinterpret_cast<__Type*>(
|
||||
reinterpret_cast<uint8_t*>(_PtrToImageBase) +
|
||||
PtrToSectionHeader->PointerToRawData
|
||||
);
|
||||
}
|
||||
|
||||
template<typename __Type>
|
||||
__Type* GetSectionView(uintptr_t Rva) const {
|
||||
auto PtrToSectionHeader = GetSectionHeader(Rva);
|
||||
|
||||
if (PtrToSectionHeader == nullptr)
|
||||
return nullptr;
|
||||
|
||||
return reinterpret_cast<__Type*>(
|
||||
reinterpret_cast<uint8_t*>(_PtrToImageBase) +
|
||||
PtrToSectionHeader->PointerToRawData
|
||||
);
|
||||
}
|
||||
|
||||
template<typename __Type>
|
||||
__Type* RvaToPointer(uintptr_t Rva) const {
|
||||
auto PtrToSectionHeader = GetSectionHeader(Rva);
|
||||
|
||||
if (PtrToSectionHeader == nullptr)
|
||||
return nullptr;
|
||||
|
||||
uint8_t* SectionViewPtr =
|
||||
reinterpret_cast<uint8_t*>(_PtrToImageBase) +
|
||||
PtrToSectionHeader->PointerToRawData;
|
||||
|
||||
return reinterpret_cast<__Type*>(
|
||||
SectionViewPtr + (Rva - PtrToSectionHeader->VirtualAddress)
|
||||
);
|
||||
}
|
||||
|
||||
bool IsRvaRangeInRelocationTable(uintptr_t Rva, size_t Size) const {
|
||||
auto v = _RelocationAddressTable.lower_bound(Rva);
|
||||
|
||||
if (v == _RelocationAddressTable.end())
|
||||
return false;
|
||||
|
||||
if (v->first == Rva) {
|
||||
return true;
|
||||
} else {
|
||||
auto w = v--;
|
||||
if (v->first <= Rva && Rva < v->first + v->second)
|
||||
return true;
|
||||
|
||||
if (Rva + Size <= w->first)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,187 @@
|
||||
#pragma once
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/blowfish.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <string>
|
||||
|
||||
#ifdef _DEBUG
|
||||
#pragma comment(lib, "libcryptoMTd.lib")
|
||||
#else
|
||||
#pragma comment(lib, "libcryptoMT.lib")
|
||||
#endif
|
||||
#pragma comment(lib, "WS2_32.lib") // some symbol are used in OpenSSL static lib
|
||||
#pragma comment(lib, "Crypt32.lib") // some symbol are used in OpenSSL static lib
|
||||
|
||||
class Navicat11Crypto {
|
||||
protected:
|
||||
BF_KEY BlowfishKey;
|
||||
|
||||
void BytesToHex(const void* src, size_t len, char* dst) {
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
char h = reinterpret_cast<const uint8_t*>(src)[i] >> 4;
|
||||
char l = reinterpret_cast<const uint8_t*>(src)[i] & 0x0F;
|
||||
|
||||
h += h >= 10 ? 'A' - 10 : '0';
|
||||
l += l >= 10 ? 'A' - 10 : '0';
|
||||
dst[2 * i] = h;
|
||||
dst[2 * i + 1] = l;
|
||||
}
|
||||
}
|
||||
|
||||
bool CheckHex(const char* src, size_t len) {
|
||||
if (len % 2 != 0)
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < len; i += 2) {
|
||||
char h = src[i];
|
||||
char l = src[i + 1];
|
||||
|
||||
if (src[i] < '0' || src[i] > 'F')
|
||||
return false;
|
||||
if (src[i] < 'A' && src[i] > '9')
|
||||
return false;
|
||||
if (src[i + 1] < '0' || src[i + 1] > 'F')
|
||||
return false;
|
||||
if (src[i + 1] < 'A' && src[i + 1] > '9')
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void HexToBytes(const char* src, size_t len, void* dst) {
|
||||
for (size_t i = 0; i < len; i += 2) {
|
||||
uint8_t h = src[i];
|
||||
uint8_t l = src[i + 1];
|
||||
|
||||
h -= h > '9' ? 'A' - 10 : '0';
|
||||
l -= l > '9' ? 'A' - 10 : '0';
|
||||
|
||||
reinterpret_cast<uint8_t*>(dst)[i / 2] = (h << 4) ^ l;
|
||||
}
|
||||
}
|
||||
|
||||
std::string EncryptString(const void* srcBytes, size_t srclen) {
|
||||
std::string ret;
|
||||
uint8_t CV[BF_BLOCK] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
||||
};
|
||||
|
||||
if (srclen == 0)
|
||||
return ret;
|
||||
|
||||
ret.resize(2 * srclen);
|
||||
|
||||
BF_ecb_encrypt(CV, CV, &BlowfishKey, BF_ENCRYPT);
|
||||
|
||||
const uint64_t* blocks = reinterpret_cast<const uint64_t*>(srcBytes);
|
||||
size_t blocks_len = srclen / BF_BLOCK;
|
||||
for (size_t i = 0; i < blocks_len; ++i) {
|
||||
union {
|
||||
uint8_t byte[8];
|
||||
uint64_t qword;
|
||||
} temp;
|
||||
|
||||
temp.qword = blocks[i];
|
||||
temp.qword ^= *reinterpret_cast<uint64_t*>(CV);
|
||||
BF_ecb_encrypt(temp.byte, temp.byte, &BlowfishKey, BF_ENCRYPT);
|
||||
*reinterpret_cast<uint64_t*>(CV) ^= temp.qword;
|
||||
BytesToHex(&temp, 8, ret.data() + 16 * i);
|
||||
}
|
||||
|
||||
if (srclen % BF_BLOCK) {
|
||||
BF_ecb_encrypt(CV, CV, &BlowfishKey, BF_ENCRYPT);
|
||||
for (size_t i = 0; i < srclen % BF_BLOCK; ++i) {
|
||||
CV[i] ^= reinterpret_cast<const uint8_t*>(blocks + blocks_len)[i];
|
||||
}
|
||||
BytesToHex(CV, srclen % BF_BLOCK, ret.data() + 16 * blocks_len);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string DecryptString(const char* srchex, size_t srclen) {
|
||||
std::string ret;
|
||||
uint8_t CV[BF_BLOCK] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
||||
};
|
||||
|
||||
if (CheckHex(srchex, srclen) == false)
|
||||
throw std::invalid_argument("Not hex string.");
|
||||
|
||||
ret.resize(srclen / 2);
|
||||
|
||||
BF_ecb_encrypt(CV, CV, &BlowfishKey, BF_ENCRYPT);
|
||||
|
||||
const char(*blocks)[16] = reinterpret_cast<const char(*)[16]>(srchex);
|
||||
size_t blocks_len = srclen / 16;
|
||||
for (size_t i = 0; i < blocks_len; ++i) {
|
||||
union {
|
||||
uint8_t byte[8];
|
||||
uint64_t qword;
|
||||
} temp, temp2;
|
||||
|
||||
HexToBytes(blocks[i], 16, temp.byte);
|
||||
temp2.qword = temp.qword;
|
||||
BF_ecb_encrypt(temp.byte, temp.byte, &BlowfishKey, BF_DECRYPT);
|
||||
temp.qword ^= *reinterpret_cast<uint64_t*>(CV);
|
||||
*reinterpret_cast<uint64_t*>(ret.data() + 8 * i) = temp.qword;
|
||||
*reinterpret_cast<uint64_t*>(CV) ^= temp2.qword;
|
||||
}
|
||||
|
||||
if (srclen % 16) {
|
||||
union {
|
||||
uint8_t byte[8];
|
||||
uint64_t qword;
|
||||
} temp = { };
|
||||
HexToBytes(blocks[blocks_len], srclen % 16, temp.byte);
|
||||
|
||||
BF_ecb_encrypt(CV, CV, &BlowfishKey, BF_ENCRYPT);
|
||||
for (size_t i = 0; i < (srclen % 16) / 2; ++i)
|
||||
ret[blocks_len * 8 + i] = temp.byte[i] ^ CV[i];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Navicat11Crypto() {
|
||||
static const uint8_t PresetKey[20] = {
|
||||
0x42, 0xCE, 0xB2, 0x71, 0xA5, 0xE4, 0x58, 0xB7,
|
||||
0x4A, 0xEA, 0x93, 0x94, 0x79, 0x22, 0x35, 0x43,
|
||||
0x91, 0x87, 0x33, 0x40
|
||||
};
|
||||
|
||||
BF_set_key(&BlowfishKey, SHA_DIGEST_LENGTH, PresetKey);
|
||||
}
|
||||
|
||||
Navicat11Crypto(const void* UserKey, size_t Length) {
|
||||
SetKey(UserKey, Length);
|
||||
}
|
||||
|
||||
void SetKey(const void* UserKey, size_t Length) {
|
||||
unsigned char MessageDigest[SHA_DIGEST_LENGTH];
|
||||
|
||||
SHA1(reinterpret_cast<const unsigned char*>(UserKey), Length, MessageDigest);
|
||||
BF_set_key(&BlowfishKey, SHA_DIGEST_LENGTH, MessageDigest);
|
||||
OPENSSL_cleanse(MessageDigest, SHA_DIGEST_LENGTH);
|
||||
}
|
||||
|
||||
std::string EncryptString(const std::string& Plaintext) {
|
||||
return EncryptString(Plaintext.c_str(), Plaintext.length());
|
||||
}
|
||||
|
||||
std::string DecryptString(const std::string& Ciphertext) {
|
||||
return DecryptString(Ciphertext.c_str(), Ciphertext.length());
|
||||
}
|
||||
|
||||
void Clear() {
|
||||
OPENSSL_cleanse(&BlowfishKey, sizeof(BlowfishKey));
|
||||
}
|
||||
|
||||
~Navicat11Crypto() {
|
||||
Clear();
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,291 +0,0 @@
|
||||
#pragma once
|
||||
#include "aes.h"
|
||||
#include "blowfish.h"
|
||||
#include "SHA1.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class Navicat11Crypto {
|
||||
protected:
|
||||
BLOWFISH_KEY BlowfishKey;
|
||||
|
||||
void BytesToHex(const void* src, size_t len, char* dst) {
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
char h = reinterpret_cast<const uint8_t*>(src)[i] >> 4;
|
||||
char l = reinterpret_cast<const uint8_t*>(src)[i] & 0x0F;
|
||||
|
||||
h += h >= 10 ? 'A' - 10 : '0';
|
||||
l += l >= 10 ? 'A' - 10 : '0';
|
||||
dst[2 * i] = h;
|
||||
dst[2 * i + 1] = l;
|
||||
}
|
||||
}
|
||||
|
||||
bool CheckHex(const char* src, size_t len) {
|
||||
if (len % 2 != 0)
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < len; i += 2) {
|
||||
char h = src[i];
|
||||
char l = src[i + 1];
|
||||
|
||||
if (src[i] < '0' || src[i] > 'F')
|
||||
return false;
|
||||
if (src[i] < 'A' && src[i] > '9')
|
||||
return false;
|
||||
if (src[i + 1] < '0' || src[i + 1] > 'F')
|
||||
return false;
|
||||
if (src[i + 1] < 'A' && src[i + 1] > '9')
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void HexToBytes(const char* src, size_t len, void* dst) {
|
||||
for (size_t i = 0; i < len; i += 2) {
|
||||
uint8_t h = src[i];
|
||||
uint8_t l = src[i + 1];
|
||||
|
||||
h -= h > '9' ? 'A' - 10 : '0';
|
||||
l -= l > '9' ? 'A' - 10 : '0';
|
||||
|
||||
reinterpret_cast<uint8_t*>(dst)[i / 2] = (h << 4 )^ l;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Navicat11Crypto() {
|
||||
const uint8_t DefaultKey[8] = {
|
||||
'3', 'D', 'C', '5', 'C', 'A', '3', '9'
|
||||
};
|
||||
SHA1_DIGEST KeyHash;
|
||||
accelc_SHA1(DefaultKey, sizeof(DefaultKey), &KeyHash);
|
||||
accelc_Blowfish_set_key(KeyHash.byte, sizeof(KeyHash), &BlowfishKey);
|
||||
}
|
||||
|
||||
Navicat11Crypto(const void* srcBytes, size_t srclen) {
|
||||
if (srclen == 0)
|
||||
srclen = BLOWFISH_MIN_KEY_LENGTH;
|
||||
if (srclen > BLOWFISH_MAX_KEY_LENGTH)
|
||||
srclen = BLOWFISH_MAX_KEY_LENGTH;
|
||||
SHA1_DIGEST KeyHash;
|
||||
accelc_SHA1(srcBytes, srclen, &KeyHash);
|
||||
accelc_Blowfish_set_key(KeyHash.byte, sizeof(KeyHash), &BlowfishKey);
|
||||
}
|
||||
|
||||
std::vector<char> EncryptString(const void* srcBytes, size_t srclen) {
|
||||
std::vector<char> ret;
|
||||
if (srclen == 0)
|
||||
return ret;
|
||||
|
||||
ret.resize(srclen * 2 + 1);
|
||||
ret[srclen * 2] = 0;
|
||||
|
||||
uint8_t CV[BLOWFISH_BLOCK_SIZE] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
||||
};
|
||||
accelc_Blowfish_encrypt(CV, &BlowfishKey, BLOWFISH_BIG_ENDIAN);
|
||||
|
||||
const uint64_t* blocks = reinterpret_cast<const uint64_t*>(srcBytes);
|
||||
size_t blocks_len = srclen / BLOWFISH_BLOCK_SIZE;
|
||||
for (size_t i = 0; i < blocks_len; ++i) {
|
||||
union {
|
||||
uint8_t byte[8];
|
||||
uint64_t qword;
|
||||
} temp;
|
||||
|
||||
temp.qword = blocks[i];
|
||||
temp.qword ^= *reinterpret_cast<uint64_t*>(CV);
|
||||
accelc_Blowfish_encrypt(temp.byte, &BlowfishKey, BLOWFISH_BIG_ENDIAN);
|
||||
*reinterpret_cast<uint64_t*>(CV) ^= temp.qword;
|
||||
|
||||
BytesToHex(temp.byte, 8, ret.data() + 16 * i);
|
||||
}
|
||||
|
||||
if (srclen % BLOWFISH_BLOCK_SIZE) {
|
||||
accelc_Blowfish_encrypt(CV, &BlowfishKey, BLOWFISH_BIG_ENDIAN);
|
||||
for (size_t i = 0; i < srclen % BLOWFISH_BLOCK_SIZE; ++i)
|
||||
CV[i] ^= reinterpret_cast<const uint8_t*>(blocks + blocks_len)[i];
|
||||
BytesToHex(CV, srclen % BLOWFISH_BLOCK_SIZE, ret.data() + 16 * blocks_len);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> DecryptString(const char* srchex, size_t srclen) {
|
||||
std::vector<uint8_t> ret;
|
||||
if (CheckHex(srchex, srclen) == false)
|
||||
return ret;
|
||||
|
||||
ret.resize(srclen / 2);
|
||||
uint8_t CV[BLOWFISH_BLOCK_SIZE] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
||||
};
|
||||
accelc_Blowfish_encrypt(CV, &BlowfishKey, BLOWFISH_BIG_ENDIAN);
|
||||
|
||||
const char (*blocks)[16] = reinterpret_cast<const char (*)[16]>(srchex);
|
||||
size_t blocks_len = srclen / 16;
|
||||
for (size_t i = 0; i < blocks_len; ++i) {
|
||||
union {
|
||||
uint8_t byte[8];
|
||||
uint64_t qword;
|
||||
} temp, temp2;
|
||||
|
||||
HexToBytes(blocks[i], 16, temp.byte);
|
||||
std::memcpy(temp2.byte, temp.byte, 8);
|
||||
accelc_Blowfish_decrypt(temp.byte, &BlowfishKey, BLOWFISH_BIG_ENDIAN);
|
||||
temp.qword ^= *reinterpret_cast<uint64_t*>(CV);
|
||||
*reinterpret_cast<uint64_t*>(ret.data() + 8 * i) = temp.qword;
|
||||
*reinterpret_cast<uint64_t*>(CV) ^= temp2.qword;
|
||||
}
|
||||
|
||||
if (srclen % 16) {
|
||||
union {
|
||||
uint8_t byte[8];
|
||||
uint64_t qword;
|
||||
} temp = { };
|
||||
HexToBytes(blocks[blocks_len], srclen % 16, temp.byte);
|
||||
|
||||
accelc_Blowfish_encrypt(CV, &BlowfishKey, BLOWFISH_BIG_ENDIAN);
|
||||
for (size_t i = 0; i < (srclen % 16) / 2; ++i)
|
||||
ret[blocks_len * 8 + i] = temp.byte[i] ^ CV[i];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class Navicat12Crypto : public Navicat11Crypto {
|
||||
protected:
|
||||
AES_KEY AES128Key;
|
||||
public:
|
||||
|
||||
Navicat12Crypto() : Navicat11Crypto() {
|
||||
uint8_t DefaultKey[16] = {
|
||||
'l', 'i', 'b', 'c', 'c', 'k', 'e', 'y',
|
||||
'l', 'i', 'b', 'c', 'c', 'k', 'e', 'y'
|
||||
};
|
||||
accelc_AES128_set_key(DefaultKey, &AES128Key);
|
||||
}
|
||||
|
||||
Navicat12Crypto(const void* srcBytes, size_t srclen) :
|
||||
Navicat11Crypto(srcBytes, srclen) {
|
||||
|
||||
uint8_t DefaultKey[16] = {
|
||||
'l', 'i', 'b', 'c', 'c', 'k', 'e', 'y',
|
||||
'l', 'i', 'b', 'c', 'c', 'k', 'e', 'y'
|
||||
};
|
||||
accelc_AES128_set_key(DefaultKey, &AES128Key);
|
||||
}
|
||||
|
||||
std::vector<char> EncryptString(const void* srcBytes, size_t srclen) {
|
||||
std::vector<char> ret;
|
||||
if (srclen == 0)
|
||||
return ret;
|
||||
|
||||
ret.resize((srclen / AES_BLOCK_SIZE + 1) * AES_BLOCK_SIZE * 2);
|
||||
union {
|
||||
uint8_t byte[AES_BLOCK_SIZE];
|
||||
uint64_t qword[2];
|
||||
} CV = {
|
||||
'l', 'i', 'b', 'c', 'c', 'i', 'v', ' ',
|
||||
'l', 'i', 'b', 'c', 'c', 'i', 'v', ' '
|
||||
};
|
||||
|
||||
const uint8_t (*blocks)[AES_BLOCK_SIZE] = reinterpret_cast<const uint8_t (*)[AES_BLOCK_SIZE]>(srcBytes);
|
||||
size_t blocks_len = srclen / AES_BLOCK_SIZE;
|
||||
for (size_t i = 0; i < blocks_len; ++i) {
|
||||
union {
|
||||
uint8_t byte[AES_BLOCK_SIZE];
|
||||
uint64_t qword[2];
|
||||
} temp;
|
||||
|
||||
std::memcpy(temp.byte, blocks[i], AES_BLOCK_SIZE);
|
||||
temp.qword[0] ^= CV.qword[0];
|
||||
temp.qword[1] ^= CV.qword[1];
|
||||
accelc_AES128_encrypt(temp.byte, &AES128Key);
|
||||
BytesToHex(temp.byte, AES_BLOCK_SIZE, ret.data() + 2 * AES_BLOCK_SIZE * i);
|
||||
CV.qword[0] = temp.qword[0];
|
||||
CV.qword[1] = temp.qword[1];
|
||||
}
|
||||
|
||||
uint8_t padding = AES_BLOCK_SIZE - srclen % AES_BLOCK_SIZE;
|
||||
union {
|
||||
uint8_t byte[AES_BLOCK_SIZE];
|
||||
uint64_t qword[2];
|
||||
} temp;
|
||||
|
||||
std::memcpy(temp.byte, blocks[blocks_len], srclen % AES_BLOCK_SIZE);
|
||||
for (size_t i = srclen % AES_BLOCK_SIZE; i < AES_BLOCK_SIZE; ++i)
|
||||
temp.byte[i] = padding;
|
||||
|
||||
temp.qword[0] ^= CV.qword[0];
|
||||
temp.qword[1] ^= CV.qword[1];
|
||||
accelc_AES128_encrypt(temp.byte, &AES128Key);
|
||||
BytesToHex(temp.byte, AES_BLOCK_SIZE, ret.data() + 2 * AES_BLOCK_SIZE * blocks_len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> DecryptString(const char* srchex, size_t srclen) {
|
||||
std::vector<uint8_t> ret;
|
||||
if (srclen % (2 * AES_BLOCK_SIZE) != 0 || CheckHex(srchex, srclen) == false)
|
||||
return ret;
|
||||
|
||||
ret.reserve(srclen / 2);
|
||||
ret.resize(srclen / 2 - AES_BLOCK_SIZE);
|
||||
union {
|
||||
uint8_t byte[AES_BLOCK_SIZE];
|
||||
uint64_t qword[2];
|
||||
} CV = {
|
||||
'l', 'i', 'b', 'c', 'c', 'i', 'v', ' ',
|
||||
'l', 'i', 'b', 'c', 'c', 'i', 'v', ' '
|
||||
};
|
||||
|
||||
const char (*blocks)[2 * AES_BLOCK_SIZE] = reinterpret_cast<const char(*)[2 * AES_BLOCK_SIZE]>(srchex);
|
||||
size_t blocks_len = srclen / (2 * AES_BLOCK_SIZE);
|
||||
for (size_t i = 0; i < blocks_len; ++i) {
|
||||
union {
|
||||
uint8_t byte[AES_BLOCK_SIZE];
|
||||
uint64_t qword[2];
|
||||
} temp, NextVector;
|
||||
|
||||
HexToBytes(blocks[i], 2 * AES_BLOCK_SIZE, temp.byte);
|
||||
std::memcpy(NextVector.byte, temp.byte, AES_BLOCK_SIZE);
|
||||
accelc_AES128_decrypt(temp.byte, &AES128Key);
|
||||
temp.qword[0] ^= CV.qword[0];
|
||||
temp.qword[1] ^= CV.qword[1];
|
||||
|
||||
std::memcpy(ret.data() + AES_BLOCK_SIZE * i, temp.byte, AES_BLOCK_SIZE);
|
||||
std::memcpy(CV.byte, NextVector.byte, AES_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
union {
|
||||
uint8_t byte[AES_BLOCK_SIZE];
|
||||
uint64_t qword[2];
|
||||
} temp;
|
||||
HexToBytes(blocks[blocks_len], 2 * AES_BLOCK_SIZE, temp.byte);
|
||||
accelc_AES128_decrypt(temp.byte, &AES128Key);
|
||||
temp.qword[0] ^= CV.qword[0];
|
||||
temp.qword[1] ^= CV.qword[1];
|
||||
|
||||
if (temp.byte[AES_BLOCK_SIZE - 1] > AES_BLOCK_SIZE) {
|
||||
ret.clear();
|
||||
return ret;
|
||||
} else {
|
||||
uint8_t padding = temp.byte[AES_BLOCK_SIZE - 1];
|
||||
for (int i = AES_BLOCK_SIZE - padding; i < AES_BLOCK_SIZE; ++i)
|
||||
if (temp.byte[i] != padding) {
|
||||
ret.clear();
|
||||
return ret;
|
||||
}
|
||||
for (int i = 0; i < (AES_BLOCK_SIZE - padding); ++i)
|
||||
ret.emplace_back(temp.byte[i]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
@@ -1,438 +0,0 @@
|
||||
#include "aes.h"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include <intrin.h>
|
||||
#else
|
||||
#include <x86intrin.h>
|
||||
#endif
|
||||
|
||||
extern const uint32_t accelc_aes_rcon[11];
|
||||
|
||||
extern const uint8_t accelc_aes_SBox[256];
|
||||
extern const uint8_t accelc_aes_InverseSBox[256];
|
||||
|
||||
extern const uint8_t accelc_aes_GF2p8_Mul_0x02[256];
|
||||
extern const uint8_t accelc_aes_GF2p8_Mul_0x03[256];
|
||||
extern const uint8_t accelc_aes_GF2p8_Mul_0x09[256];
|
||||
extern const uint8_t accelc_aes_GF2p8_Mul_0x0B[256];
|
||||
extern const uint8_t accelc_aes_GF2p8_Mul_0x0D[256];
|
||||
extern const uint8_t accelc_aes_GF2p8_Mul_0x0E[256];
|
||||
|
||||
#define Swap(X, Y, Temp) \
|
||||
Temp = X; \
|
||||
X = Y; \
|
||||
Y = Temp;
|
||||
|
||||
void accelc_AES128_encrypt(uint8_t srcBytes[AES_BLOCK_SIZE], const AES_KEY* srcKey) {
|
||||
|
||||
((uint64_t*)srcBytes)[0] ^= srcKey->qword[0];
|
||||
((uint64_t*)srcBytes)[1] ^= srcKey->qword[1];
|
||||
|
||||
uint8_t ShiftTemp = 0;
|
||||
for (int i = 1; i < 10; ++i) {
|
||||
|
||||
for (int j = 0; j < 16; ++j)
|
||||
srcBytes[j] = accelc_aes_SBox[srcBytes[j]];
|
||||
|
||||
//Shift rows starts;
|
||||
//Shift the second row;
|
||||
Swap(srcBytes[1], srcBytes[5], ShiftTemp)
|
||||
Swap(srcBytes[5], srcBytes[9], ShiftTemp)
|
||||
Swap(srcBytes[9], srcBytes[13], ShiftTemp)
|
||||
//Shift the third row;
|
||||
Swap(srcBytes[2], srcBytes[10], ShiftTemp)
|
||||
Swap(srcBytes[6], srcBytes[14], ShiftTemp)
|
||||
//Shift the fourth row;
|
||||
Swap(srcBytes[3], srcBytes[15], ShiftTemp)
|
||||
Swap(srcBytes[15], srcBytes[11], ShiftTemp)
|
||||
Swap(srcBytes[11], srcBytes[7], ShiftTemp)
|
||||
//Shift rows ends;
|
||||
|
||||
|
||||
for (int j = 0; j < 16; j += 4) {
|
||||
uint8_t temp[4];
|
||||
*(uint32_t*)temp = ((uint32_t*)srcBytes)[j / 4];
|
||||
|
||||
srcBytes[j] = (uint8_t)(accelc_aes_GF2p8_Mul_0x02[temp[0]] ^ accelc_aes_GF2p8_Mul_0x03[temp[1]] ^ temp[2] ^ temp[3]);
|
||||
srcBytes[j + 1] = (uint8_t)(temp[0] ^ accelc_aes_GF2p8_Mul_0x02[temp[1]] ^ accelc_aes_GF2p8_Mul_0x03[temp[2]] ^ temp[3]);
|
||||
srcBytes[j + 2] = (uint8_t)(temp[0] ^ temp[1] ^ accelc_aes_GF2p8_Mul_0x02[temp[2]] ^ accelc_aes_GF2p8_Mul_0x03[temp[3]]);
|
||||
srcBytes[j + 3] = (uint8_t)(accelc_aes_GF2p8_Mul_0x03[temp[0]] ^ temp[1] ^ temp[2] ^ accelc_aes_GF2p8_Mul_0x02[temp[3]]);
|
||||
}
|
||||
|
||||
((uint64_t*)(srcBytes))[0] ^= srcKey->qword[i * 2];
|
||||
((uint64_t*)(srcBytes))[1] ^= srcKey->qword[i * 2 + 1];
|
||||
}
|
||||
|
||||
for (int j = 0; j < 16; ++j)
|
||||
srcBytes[j] = accelc_aes_SBox[srcBytes[j]];
|
||||
|
||||
//Shift rows starts;
|
||||
//Shift the second row;
|
||||
Swap(srcBytes[1], srcBytes[5], ShiftTemp)
|
||||
Swap(srcBytes[5], srcBytes[9], ShiftTemp)
|
||||
Swap(srcBytes[9], srcBytes[13], ShiftTemp)
|
||||
//Shift the third row;
|
||||
Swap(srcBytes[2], srcBytes[10], ShiftTemp)
|
||||
Swap(srcBytes[6], srcBytes[14], ShiftTemp)
|
||||
//Shift the fourth row;
|
||||
Swap(srcBytes[3], srcBytes[15], ShiftTemp)
|
||||
Swap(srcBytes[15], srcBytes[11], ShiftTemp)
|
||||
Swap(srcBytes[11], srcBytes[7], ShiftTemp)
|
||||
//Shift rows ends;
|
||||
|
||||
((uint64_t*)srcBytes)[0] ^= srcKey->qword[20];
|
||||
((uint64_t*)srcBytes)[1] ^= srcKey->qword[21];
|
||||
}
|
||||
|
||||
void accelc_AES128_decrypt(uint8_t srcBytes[AES_BLOCK_SIZE], const AES_KEY* srcKey) {
|
||||
((uint64_t*)srcBytes)[0] ^= srcKey->qword[20];
|
||||
((uint64_t*)srcBytes)[1] ^= srcKey->qword[21];
|
||||
|
||||
uint8_t ShiftTemp = 0;
|
||||
|
||||
for (int i = 9; i > 0; --i) {
|
||||
//Inverse Shift rows starts;
|
||||
//Inverse shift the second row;
|
||||
Swap(srcBytes[13], srcBytes[9], ShiftTemp)
|
||||
Swap(srcBytes[9], srcBytes[5], ShiftTemp)
|
||||
Swap(srcBytes[5], srcBytes[1], ShiftTemp)
|
||||
//Inverse shift the third row;
|
||||
Swap(srcBytes[14], srcBytes[6], ShiftTemp)
|
||||
Swap(srcBytes[10], srcBytes[2], ShiftTemp)
|
||||
//Inverse shift the fourth row;
|
||||
Swap(srcBytes[3], srcBytes[7], ShiftTemp)
|
||||
Swap(srcBytes[7], srcBytes[11], ShiftTemp)
|
||||
Swap(srcBytes[11], srcBytes[15], ShiftTemp)
|
||||
|
||||
for (int j = 0; j < 16; ++j)
|
||||
srcBytes[j] = accelc_aes_InverseSBox[srcBytes[j]];
|
||||
|
||||
((uint64_t*)srcBytes)[0] ^= srcKey->qword[i * 2];
|
||||
((uint64_t*)srcBytes)[1] ^= srcKey->qword[i * 2 + 1];
|
||||
|
||||
for (int j = 0; j < 16; j += 4) {
|
||||
uint8_t temp[4];
|
||||
*(uint32_t*)temp = ((uint32_t*)srcBytes)[j / 4];
|
||||
srcBytes[j] = (uint8_t)(accelc_aes_GF2p8_Mul_0x0E[temp[0]] ^ accelc_aes_GF2p8_Mul_0x0B[temp[1]] ^ accelc_aes_GF2p8_Mul_0x0D[temp[2]] ^ accelc_aes_GF2p8_Mul_0x09[temp[3]]);
|
||||
srcBytes[j + 1] = (uint8_t)(accelc_aes_GF2p8_Mul_0x09[temp[0]] ^ accelc_aes_GF2p8_Mul_0x0E[temp[1]] ^ accelc_aes_GF2p8_Mul_0x0B[temp[2]] ^ accelc_aes_GF2p8_Mul_0x0D[temp[3]]);
|
||||
srcBytes[j + 2] = (uint8_t)(accelc_aes_GF2p8_Mul_0x0D[temp[0]] ^ accelc_aes_GF2p8_Mul_0x09[temp[1]] ^ accelc_aes_GF2p8_Mul_0x0E[temp[2]] ^ accelc_aes_GF2p8_Mul_0x0B[temp[3]]);
|
||||
srcBytes[j + 3] = (uint8_t)(accelc_aes_GF2p8_Mul_0x0B[temp[0]] ^ accelc_aes_GF2p8_Mul_0x0D[temp[1]] ^ accelc_aes_GF2p8_Mul_0x09[temp[2]] ^ accelc_aes_GF2p8_Mul_0x0E[temp[3]]);
|
||||
}
|
||||
}
|
||||
|
||||
//Inverse Shift rows starts;
|
||||
//Inverse shift the second row;
|
||||
Swap(srcBytes[13], srcBytes[9], ShiftTemp)
|
||||
Swap(srcBytes[9], srcBytes[5], ShiftTemp)
|
||||
Swap(srcBytes[5], srcBytes[1], ShiftTemp)
|
||||
//Inverse shift the third row;
|
||||
Swap(srcBytes[14], srcBytes[6], ShiftTemp)
|
||||
Swap(srcBytes[10], srcBytes[2], ShiftTemp)
|
||||
//Inverse shift the fourth row;
|
||||
Swap(srcBytes[3], srcBytes[7], ShiftTemp)
|
||||
Swap(srcBytes[7], srcBytes[11], ShiftTemp)
|
||||
Swap(srcBytes[11], srcBytes[15], ShiftTemp)
|
||||
|
||||
for (int j = 0; j < 16; ++j)
|
||||
srcBytes[j] = accelc_aes_InverseSBox[srcBytes[j]];
|
||||
|
||||
((uint64_t*)srcBytes)[0] ^= srcKey->qword[0];
|
||||
((uint64_t*)srcBytes)[1] ^= srcKey->qword[1];
|
||||
}
|
||||
|
||||
void accelc_AES128_set_key(const uint8_t srcUserKey[16], AES_KEY* dstKey) {
|
||||
dstKey->qword[0] = ((const uint64_t*)srcUserKey)[0];
|
||||
dstKey->qword[1] = ((const uint64_t*)srcUserKey)[1];
|
||||
|
||||
for (int i = 4; i < 44; ++i) {
|
||||
uint32_t temp = dstKey->dword[i - 1];
|
||||
if (i % 4 == 0) {
|
||||
temp = _rotr(temp, 8);
|
||||
((uint8_t*)&temp)[0] = accelc_aes_SBox[((uint8_t*)&temp)[0]];
|
||||
((uint8_t*)&temp)[1] = accelc_aes_SBox[((uint8_t*)&temp)[1]];
|
||||
((uint8_t*)&temp)[2] = accelc_aes_SBox[((uint8_t*)&temp)[2]];
|
||||
((uint8_t*)&temp)[3] = accelc_aes_SBox[((uint8_t*)&temp)[3]];
|
||||
temp ^= accelc_aes_rcon[i / 4];
|
||||
}
|
||||
dstKey->dword[i] = dstKey->dword[i - 4] ^ temp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void accelc_AES192_encrypt(uint8_t srcBytes[AES_BLOCK_SIZE], const AES_KEY* srcKey) {
|
||||
((uint64_t*)srcBytes)[0] ^= srcKey->qword[0];
|
||||
((uint64_t*)srcBytes)[1] ^= srcKey->qword[1];
|
||||
|
||||
uint8_t ShiftTemp = 0;
|
||||
for (int i = 1; i < 12; ++i) {
|
||||
|
||||
for (int j = 0; j < 16; ++j)
|
||||
srcBytes[j] = accelc_aes_SBox[srcBytes[j]];
|
||||
|
||||
//Shift rows starts;
|
||||
//Shift the second row;
|
||||
Swap(srcBytes[1], srcBytes[5], ShiftTemp)
|
||||
Swap(srcBytes[5], srcBytes[9], ShiftTemp)
|
||||
Swap(srcBytes[9], srcBytes[13], ShiftTemp)
|
||||
//Shift the third row;
|
||||
Swap(srcBytes[2], srcBytes[10], ShiftTemp)
|
||||
Swap(srcBytes[6], srcBytes[14], ShiftTemp)
|
||||
//Shift the fourth row;
|
||||
Swap(srcBytes[3], srcBytes[15], ShiftTemp)
|
||||
Swap(srcBytes[15], srcBytes[11], ShiftTemp)
|
||||
Swap(srcBytes[11], srcBytes[7], ShiftTemp)
|
||||
//Shift rows ends;
|
||||
|
||||
for (int j = 0; j < 16; j += 4) {
|
||||
uint8_t temp[4];
|
||||
*(uint32_t*)temp = ((uint32_t*)srcBytes)[j / 4];
|
||||
|
||||
srcBytes[j] = (uint8_t)(accelc_aes_GF2p8_Mul_0x02[temp[0]] ^ accelc_aes_GF2p8_Mul_0x03[temp[1]] ^ temp[2] ^ temp[3]);
|
||||
srcBytes[j + 1] = (uint8_t)(temp[0] ^ accelc_aes_GF2p8_Mul_0x02[temp[1]] ^ accelc_aes_GF2p8_Mul_0x03[temp[2]] ^ temp[3]);
|
||||
srcBytes[j + 2] = (uint8_t)(temp[0] ^ temp[1] ^ accelc_aes_GF2p8_Mul_0x02[temp[2]] ^ accelc_aes_GF2p8_Mul_0x03[temp[3]]);
|
||||
srcBytes[j + 3] = (uint8_t)(accelc_aes_GF2p8_Mul_0x03[temp[0]] ^ temp[1] ^ temp[2] ^ accelc_aes_GF2p8_Mul_0x02[temp[3]]);
|
||||
}
|
||||
|
||||
((uint64_t*)srcBytes)[0] ^= srcKey->qword[i * 2];
|
||||
((uint64_t*)srcBytes)[1] ^= srcKey->qword[i * 2 + 1];
|
||||
}
|
||||
|
||||
for (int j = 0; j < 16; ++j)
|
||||
srcBytes[j] = accelc_aes_SBox[srcBytes[j]];
|
||||
|
||||
//Shift rows starts;
|
||||
//Shift the second row;
|
||||
Swap(srcBytes[1], srcBytes[5], ShiftTemp) //Swap is a MACRO, no need to add ';'.
|
||||
Swap(srcBytes[5], srcBytes[9], ShiftTemp)
|
||||
Swap(srcBytes[9], srcBytes[13], ShiftTemp)
|
||||
//Shift the third row;
|
||||
Swap(srcBytes[2], srcBytes[10], ShiftTemp)
|
||||
Swap(srcBytes[6], srcBytes[14], ShiftTemp)
|
||||
//Shift the fourth row;
|
||||
Swap(srcBytes[3], srcBytes[15], ShiftTemp)
|
||||
Swap(srcBytes[15], srcBytes[11], ShiftTemp)
|
||||
Swap(srcBytes[11], srcBytes[7], ShiftTemp)
|
||||
//Shift rows ends;
|
||||
|
||||
((uint64_t*)srcBytes)[0] ^= srcKey->qword[24];
|
||||
((uint64_t*)srcBytes)[1] ^= srcKey->qword[25];
|
||||
}
|
||||
|
||||
void accelc_AES192_decrypt(uint8_t srcBytes[AES_BLOCK_SIZE], const AES_KEY* srcKey) {
|
||||
((uint64_t*)srcBytes)[0] ^= srcKey->qword[24];
|
||||
((uint64_t*)srcBytes)[1] ^= srcKey->qword[25];
|
||||
|
||||
uint8_t ShiftTemp = 0;
|
||||
|
||||
for (int i = 11; i > 0; --i) {
|
||||
//Inverse Shift rows starts;
|
||||
//Inverse shift the second row;
|
||||
Swap(srcBytes[13], srcBytes[9], ShiftTemp)
|
||||
Swap(srcBytes[9], srcBytes[5], ShiftTemp)
|
||||
Swap(srcBytes[5], srcBytes[1], ShiftTemp)
|
||||
//Inverse shift the third row;
|
||||
Swap(srcBytes[14], srcBytes[6], ShiftTemp)
|
||||
Swap(srcBytes[10], srcBytes[2], ShiftTemp)
|
||||
//Inverse shift the fourth row;
|
||||
Swap(srcBytes[3], srcBytes[7], ShiftTemp)
|
||||
Swap(srcBytes[7], srcBytes[11], ShiftTemp)
|
||||
Swap(srcBytes[11], srcBytes[15], ShiftTemp)
|
||||
|
||||
for (int j = 0; j < 16; ++j)
|
||||
srcBytes[j] = accelc_aes_InverseSBox[srcBytes[j]];
|
||||
|
||||
((uint64_t*)srcBytes)[0] ^= srcKey->qword[i * 2];
|
||||
((uint64_t*)srcBytes)[1] ^= srcKey->qword[i * 2 + 1];
|
||||
|
||||
for (int j = 0; j < 16; j += 4) {
|
||||
uint8_t temp[4];
|
||||
*(uint32_t*)temp = ((uint32_t*)srcBytes)[j / 4];
|
||||
srcBytes[j] = (uint8_t)(accelc_aes_GF2p8_Mul_0x0E[temp[0]] ^ accelc_aes_GF2p8_Mul_0x0B[temp[1]] ^ accelc_aes_GF2p8_Mul_0x0D[temp[2]] ^ accelc_aes_GF2p8_Mul_0x09[temp[3]]);
|
||||
srcBytes[j + 1] = (uint8_t)(accelc_aes_GF2p8_Mul_0x09[temp[0]] ^ accelc_aes_GF2p8_Mul_0x0E[temp[1]] ^ accelc_aes_GF2p8_Mul_0x0B[temp[2]] ^ accelc_aes_GF2p8_Mul_0x0D[temp[3]]);
|
||||
srcBytes[j + 2] = (uint8_t)(accelc_aes_GF2p8_Mul_0x0D[temp[0]] ^ accelc_aes_GF2p8_Mul_0x09[temp[1]] ^ accelc_aes_GF2p8_Mul_0x0E[temp[2]] ^ accelc_aes_GF2p8_Mul_0x0B[temp[3]]);
|
||||
srcBytes[j + 3] = (uint8_t)(accelc_aes_GF2p8_Mul_0x0B[temp[0]] ^ accelc_aes_GF2p8_Mul_0x0D[temp[1]] ^ accelc_aes_GF2p8_Mul_0x09[temp[2]] ^ accelc_aes_GF2p8_Mul_0x0E[temp[3]]);
|
||||
}
|
||||
}
|
||||
|
||||
//Inverse Shift rows starts;
|
||||
//Inverse shift the second row;
|
||||
Swap(srcBytes[13], srcBytes[9], ShiftTemp)
|
||||
Swap(srcBytes[9], srcBytes[5], ShiftTemp)
|
||||
Swap(srcBytes[5], srcBytes[1], ShiftTemp)
|
||||
//Inverse shift the third row;
|
||||
Swap(srcBytes[14], srcBytes[6], ShiftTemp)
|
||||
Swap(srcBytes[10], srcBytes[2], ShiftTemp)
|
||||
//Inverse shift the fourth row;
|
||||
Swap(srcBytes[3], srcBytes[7], ShiftTemp)
|
||||
Swap(srcBytes[7], srcBytes[11], ShiftTemp)
|
||||
Swap(srcBytes[11], srcBytes[15], ShiftTemp)
|
||||
|
||||
for (uint8_t j = 0; j < 16; ++j)
|
||||
srcBytes[j] = accelc_aes_InverseSBox[srcBytes[j]];
|
||||
|
||||
((uint64_t*)srcBytes)[0] ^= srcKey->qword[0];
|
||||
((uint64_t*)srcBytes)[1] ^= srcKey->qword[1];
|
||||
}
|
||||
|
||||
void accelc_AES192_set_key(const uint8_t srcUserKey[24], AES_KEY* dstKey) {
|
||||
dstKey->qword[0] = ((const uint64_t*)srcUserKey)[0];
|
||||
dstKey->qword[1] = ((const uint64_t*)srcUserKey)[1];
|
||||
dstKey->qword[2] = ((const uint64_t*)srcUserKey)[2];
|
||||
|
||||
for (int i = 6; i < 52; ++i) {
|
||||
uint32_t temp = dstKey->dword[i - 1];
|
||||
if (i % 6 == 0) {
|
||||
temp = _rotr(temp, 8);
|
||||
((uint8_t*)&temp)[0] = accelc_aes_SBox[((uint8_t*)&temp)[0]];
|
||||
((uint8_t*)&temp)[1] = accelc_aes_SBox[((uint8_t*)&temp)[1]];
|
||||
((uint8_t*)&temp)[2] = accelc_aes_SBox[((uint8_t*)&temp)[2]];
|
||||
((uint8_t*)&temp)[3] = accelc_aes_SBox[((uint8_t*)&temp)[3]];
|
||||
temp ^= accelc_aes_rcon[i / 6];
|
||||
}
|
||||
dstKey->dword[i] = dstKey->dword[i - 6] ^ temp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void accelc_AES256_encrypt(uint8_t srcBytes[AES_BLOCK_SIZE], const AES_KEY* srcKey) {
|
||||
((uint64_t*)srcBytes)[0] ^= srcKey->qword[0];
|
||||
((uint64_t*)srcBytes)[1] ^= srcKey->qword[1];
|
||||
|
||||
uint8_t ShiftTemp = 0;
|
||||
for (int i = 1; i < 14; ++i) {
|
||||
|
||||
for (int j = 0; j < 16; ++j)
|
||||
srcBytes[j] = accelc_aes_SBox[srcBytes[j]];
|
||||
|
||||
//Shift rows starts;
|
||||
//Shift the second row;
|
||||
Swap(srcBytes[1], srcBytes[5], ShiftTemp)
|
||||
Swap(srcBytes[5], srcBytes[9], ShiftTemp)
|
||||
Swap(srcBytes[9], srcBytes[13], ShiftTemp)
|
||||
//Shift the third row;
|
||||
Swap(srcBytes[2], srcBytes[10], ShiftTemp)
|
||||
Swap(srcBytes[6], srcBytes[14], ShiftTemp)
|
||||
//Shift the fourth row;
|
||||
Swap(srcBytes[3], srcBytes[15], ShiftTemp)
|
||||
Swap(srcBytes[15], srcBytes[11], ShiftTemp)
|
||||
Swap(srcBytes[11], srcBytes[7], ShiftTemp)
|
||||
//Shift rows ends;
|
||||
|
||||
for (int j = 0; j < 16; j += 4) {
|
||||
uint8_t temp[4];
|
||||
*(uint32_t*)temp = ((uint32_t*)srcBytes)[j / 4];
|
||||
|
||||
srcBytes[j] = (uint8_t)(accelc_aes_GF2p8_Mul_0x02[temp[0]] ^ accelc_aes_GF2p8_Mul_0x03[temp[1]] ^ temp[2] ^ temp[3]);
|
||||
srcBytes[j + 1] = (uint8_t)(temp[0] ^ accelc_aes_GF2p8_Mul_0x02[temp[1]] ^ accelc_aes_GF2p8_Mul_0x03[temp[2]] ^ temp[3]);
|
||||
srcBytes[j + 2] = (uint8_t)(temp[0] ^ temp[1] ^ accelc_aes_GF2p8_Mul_0x02[temp[2]] ^ accelc_aes_GF2p8_Mul_0x03[temp[3]]);
|
||||
srcBytes[j + 3] = (uint8_t)(accelc_aes_GF2p8_Mul_0x03[temp[0]] ^ temp[1] ^ temp[2] ^ accelc_aes_GF2p8_Mul_0x02[temp[3]]);
|
||||
}
|
||||
|
||||
((uint64_t*)srcBytes)[0] ^= srcKey->qword[i * 2];
|
||||
((uint64_t*)srcBytes)[1] ^= srcKey->qword[i * 2 + 1];
|
||||
}
|
||||
|
||||
for (int j = 0; j < 16; ++j)
|
||||
srcBytes[j] = accelc_aes_SBox[srcBytes[j]];
|
||||
|
||||
//Shift rows starts;
|
||||
//Shift the second row;
|
||||
Swap(srcBytes[1], srcBytes[5], ShiftTemp)
|
||||
Swap(srcBytes[5], srcBytes[9], ShiftTemp)
|
||||
Swap(srcBytes[9], srcBytes[13], ShiftTemp)
|
||||
//Shift the third row;
|
||||
Swap(srcBytes[2], srcBytes[10], ShiftTemp)
|
||||
Swap(srcBytes[6], srcBytes[14], ShiftTemp)
|
||||
//Shift the fourth row;
|
||||
Swap(srcBytes[3], srcBytes[15], ShiftTemp)
|
||||
Swap(srcBytes[15], srcBytes[11], ShiftTemp)
|
||||
Swap(srcBytes[11], srcBytes[7], ShiftTemp)
|
||||
//Shift rows ends;
|
||||
|
||||
((uint64_t*)srcBytes)[0] ^= srcKey->qword[28];
|
||||
((uint64_t*)srcBytes)[1] ^= srcKey->qword[29];
|
||||
}
|
||||
|
||||
void accelc_AES256_decrypt(uint8_t srcBytes[AES_BLOCK_SIZE], const AES_KEY* srcKey) {
|
||||
((uint64_t*)srcBytes)[0] ^= srcKey->qword[28];
|
||||
((uint64_t*)srcBytes)[1] ^= srcKey->qword[29];
|
||||
|
||||
uint8_t ShiftTemp = 0;
|
||||
for (int i = 13; i > 0; --i) {
|
||||
//Inverse Shift rows starts;
|
||||
//Inverse shift the second row;
|
||||
Swap(srcBytes[13], srcBytes[9], ShiftTemp)
|
||||
Swap(srcBytes[9], srcBytes[5], ShiftTemp)
|
||||
Swap(srcBytes[5], srcBytes[1], ShiftTemp)
|
||||
//Inverse shift the third row;
|
||||
Swap(srcBytes[14], srcBytes[6], ShiftTemp)
|
||||
Swap(srcBytes[10], srcBytes[2], ShiftTemp)
|
||||
//Inverse shift the fourth row;
|
||||
Swap(srcBytes[3], srcBytes[7], ShiftTemp)
|
||||
Swap(srcBytes[7], srcBytes[11], ShiftTemp)
|
||||
Swap(srcBytes[11], srcBytes[15], ShiftTemp)
|
||||
|
||||
for (int j = 0; j < 16; ++j)
|
||||
srcBytes[j] = accelc_aes_InverseSBox[srcBytes[j]];
|
||||
|
||||
((uint64_t*)srcBytes)[0] ^= srcKey->qword[i * 2];
|
||||
((uint64_t*)srcBytes)[1] ^= srcKey->qword[i * 2 + 1];
|
||||
|
||||
for (int j = 0; j < 16; j += 4) {
|
||||
uint8_t temp[4];
|
||||
*(uint32_t*)temp = ((uint32_t*)srcBytes)[j / 4];
|
||||
|
||||
srcBytes[j] = (uint8_t)(accelc_aes_GF2p8_Mul_0x0E[temp[0]] ^ accelc_aes_GF2p8_Mul_0x0B[temp[1]] ^ accelc_aes_GF2p8_Mul_0x0D[temp[2]] ^ accelc_aes_GF2p8_Mul_0x09[temp[3]]);
|
||||
srcBytes[j + 1] = (uint8_t)(accelc_aes_GF2p8_Mul_0x09[temp[0]] ^ accelc_aes_GF2p8_Mul_0x0E[temp[1]] ^ accelc_aes_GF2p8_Mul_0x0B[temp[2]] ^ accelc_aes_GF2p8_Mul_0x0D[temp[3]]);
|
||||
srcBytes[j + 2] = (uint8_t)(accelc_aes_GF2p8_Mul_0x0D[temp[0]] ^ accelc_aes_GF2p8_Mul_0x09[temp[1]] ^ accelc_aes_GF2p8_Mul_0x0E[temp[2]] ^ accelc_aes_GF2p8_Mul_0x0B[temp[3]]);
|
||||
srcBytes[j + 3] = (uint8_t)(accelc_aes_GF2p8_Mul_0x0B[temp[0]] ^ accelc_aes_GF2p8_Mul_0x0D[temp[1]] ^ accelc_aes_GF2p8_Mul_0x09[temp[2]] ^ accelc_aes_GF2p8_Mul_0x0E[temp[3]]);
|
||||
}
|
||||
}
|
||||
|
||||
//Inverse Shift rows starts;
|
||||
//Inverse shift the second row;
|
||||
Swap(srcBytes[13], srcBytes[9], ShiftTemp)
|
||||
Swap(srcBytes[9], srcBytes[5], ShiftTemp)
|
||||
Swap(srcBytes[5], srcBytes[1], ShiftTemp)
|
||||
//Inverse shift the third row;
|
||||
Swap(srcBytes[14], srcBytes[6], ShiftTemp)
|
||||
Swap(srcBytes[10], srcBytes[2], ShiftTemp)
|
||||
//Inverse shift the fourth row;
|
||||
Swap(srcBytes[3], srcBytes[7], ShiftTemp)
|
||||
Swap(srcBytes[7], srcBytes[11], ShiftTemp)
|
||||
Swap(srcBytes[11], srcBytes[15], ShiftTemp)
|
||||
|
||||
for (int j = 0; j < 16; ++j)
|
||||
srcBytes[j] = accelc_aes_InverseSBox[srcBytes[j]];
|
||||
|
||||
((uint64_t*)srcBytes)[0] ^= srcKey->qword[0];
|
||||
((uint64_t*)srcBytes)[1] ^= srcKey->qword[1];
|
||||
}
|
||||
|
||||
void accelc_AES256_set_key(const uint8_t srcUserKey[32], AES_KEY* dstKey) {
|
||||
dstKey->qword[0] = ((const uint64_t*)srcUserKey)[0];
|
||||
dstKey->qword[1] = ((const uint64_t*)srcUserKey)[1];
|
||||
dstKey->qword[2] = ((const uint64_t*)srcUserKey)[2];
|
||||
dstKey->qword[3] = ((const uint64_t*)srcUserKey)[3];
|
||||
|
||||
for (int i = 8; i < 60; ++i) {
|
||||
uint32_t temp = dstKey->dword[i - 1];
|
||||
if (i % 8 == 0) {
|
||||
temp = _rotr(temp, 8);
|
||||
((uint8_t*)&temp)[0] = accelc_aes_SBox[((uint8_t*)&temp)[0]];
|
||||
((uint8_t*)&temp)[1] = accelc_aes_SBox[((uint8_t*)&temp)[1]];
|
||||
((uint8_t*)&temp)[2] = accelc_aes_SBox[((uint8_t*)&temp)[2]];
|
||||
((uint8_t*)&temp)[3] = accelc_aes_SBox[((uint8_t*)&temp)[3]];
|
||||
temp ^= accelc_aes_rcon[i / 8];
|
||||
}
|
||||
if (i % 8 == 4) {
|
||||
((uint8_t*)&temp)[0] = accelc_aes_SBox[((uint8_t*)&temp)[0]];
|
||||
((uint8_t*)&temp)[1] = accelc_aes_SBox[((uint8_t*)&temp)[1]];
|
||||
((uint8_t*)&temp)[2] = accelc_aes_SBox[((uint8_t*)&temp)[2]];
|
||||
((uint8_t*)&temp)[3] = accelc_aes_SBox[((uint8_t*)&temp)[3]];
|
||||
}
|
||||
dstKey->dword[i] = dstKey->dword[i - 8] ^ temp;
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define AES_BLOCK_SIZE 16
|
||||
#define AES128_USERKEY_LENGTH 16
|
||||
#define AES192_USERKEY_LENGTH 24
|
||||
#define AES256_USERKEY_LENGTH 32
|
||||
|
||||
typedef struct _AES_KEY {
|
||||
union {
|
||||
uint8_t byte[240];
|
||||
uint16_t word[120];
|
||||
uint32_t dword[60];
|
||||
uint64_t qword[30];
|
||||
};
|
||||
} AES_KEY;
|
||||
|
||||
//
|
||||
// encrypt
|
||||
//
|
||||
void accelc_AES128_encrypt(uint8_t srcBytes[AES_BLOCK_SIZE], const AES_KEY* srcKey);
|
||||
void accelc_AES192_encrypt(uint8_t srcBytes[AES_BLOCK_SIZE], const AES_KEY* srcKey);
|
||||
void accelc_AES256_encrypt(uint8_t srcBytes[AES_BLOCK_SIZE], const AES_KEY* srcKey);
|
||||
|
||||
//
|
||||
// dncrypt
|
||||
//
|
||||
void accelc_AES128_decrypt(uint8_t srcBytes[AES_BLOCK_SIZE], const AES_KEY* srcKey);
|
||||
void accelc_AES192_decrypt(uint8_t srcBytes[AES_BLOCK_SIZE], const AES_KEY* srcKey);
|
||||
void accelc_AES256_decrypt(uint8_t srcBytes[AES_BLOCK_SIZE], const AES_KEY* srcKey);
|
||||
|
||||
//
|
||||
// set_key
|
||||
//
|
||||
void accelc_AES128_set_key(const uint8_t srcUserKey[AES128_USERKEY_LENGTH], AES_KEY* dstKey);
|
||||
void accelc_AES192_set_key(const uint8_t srcUserKey[AES192_USERKEY_LENGTH], AES_KEY* dstKey);
|
||||
void accelc_AES256_set_key(const uint8_t srcUserKey[AES256_USERKEY_LENGTH], AES_KEY* dstKey);
|
||||
|
||||
//
|
||||
// encrypt_aesni
|
||||
//
|
||||
void accelc_AES128_encrypt_aesni(uint8_t srcBytes[AES_BLOCK_SIZE], const AES_KEY* srcKey);
|
||||
void accelc_AES192_encrypt_aesni(uint8_t srcBytes[AES_BLOCK_SIZE], const AES_KEY* srcKey);
|
||||
void accelc_AES256_encrypt_aesni(uint8_t srcBytes[AES_BLOCK_SIZE], const AES_KEY* srcKey);
|
||||
|
||||
//
|
||||
// decrypt_aesni
|
||||
//
|
||||
void accelc_AES128_decrypt_aesni(uint8_t srcBytes[AES_BLOCK_SIZE], const AES_KEY* srcKey);
|
||||
void accelc_AES192_decrypt_aesni(uint8_t srcBytes[AES_BLOCK_SIZE], const AES_KEY* srcKey);
|
||||
void accelc_AES256_decrypt_aesni(uint8_t srcBytes[AES_BLOCK_SIZE], const AES_KEY* srcKey);
|
||||
|
||||
//
|
||||
// decrypt_aesni_fast
|
||||
//
|
||||
void accelc_AES128_decrypt_aesni_fast(uint8_t srcBytes[AES_BLOCK_SIZE], const AES_KEY* srcInverseKey);
|
||||
void accelc_AES192_decrypt_aesni_fast(uint8_t srcBytes[AES_BLOCK_SIZE], const AES_KEY* srcInverseKey);
|
||||
void accelc_AES256_decrypt_aesni_fast(uint8_t srcBytes[AES_BLOCK_SIZE], const AES_KEY* srcInverseKey);
|
||||
|
||||
//
|
||||
// set_key_aesni
|
||||
//
|
||||
void accelc_AES128_set_key_aesni(const uint8_t srcUserKey[AES128_USERKEY_LENGTH], AES_KEY* dstKey);
|
||||
void accelc_AES192_set_key_aesni(const uint8_t srcUserKey[AES128_USERKEY_LENGTH], AES_KEY* dstKey);
|
||||
void accelc_AES256_set_key_aesni(const uint8_t srcUserKey[AES256_USERKEY_LENGTH], AES_KEY* dstKey);
|
||||
|
||||
//
|
||||
// set_invkey_aesni
|
||||
//
|
||||
void accelc_AES128_set_invkey_aesni(const AES_KEY* __restrict srcKey, AES_KEY* __restrict dstInverseKey);
|
||||
void accelc_AES192_set_invkey_aesni(const AES_KEY* __restrict srcKey, AES_KEY* __restrict dstInverseKey);
|
||||
void accelc_AES256_set_invkey_aesni(const AES_KEY* __restrict srcKey, AES_KEY* __restrict dstInverseKey);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,157 +0,0 @@
|
||||
#include <stdint.h>
|
||||
|
||||
const uint8_t accelc_aes_SBox[256] = {
|
||||
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
|
||||
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
|
||||
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
|
||||
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
|
||||
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
|
||||
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
|
||||
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
|
||||
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
|
||||
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
|
||||
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
|
||||
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
|
||||
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
|
||||
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
|
||||
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
|
||||
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
|
||||
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
|
||||
};
|
||||
|
||||
const uint32_t accelc_aes_rcon[11] = {
|
||||
0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36
|
||||
};
|
||||
|
||||
const uint8_t accelc_aes_GF2p8_Mul_0x02[256] = {
|
||||
0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E,
|
||||
0x20, 0x22, 0x24, 0x26, 0x28, 0x2A, 0x2C, 0x2E, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3A, 0x3C, 0x3E,
|
||||
0x40, 0x42, 0x44, 0x46, 0x48, 0x4A, 0x4C, 0x4E, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5A, 0x5C, 0x5E,
|
||||
0x60, 0x62, 0x64, 0x66, 0x68, 0x6A, 0x6C, 0x6E, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7A, 0x7C, 0x7E,
|
||||
0x80, 0x82, 0x84, 0x86, 0x88, 0x8A, 0x8C, 0x8E, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9A, 0x9C, 0x9E,
|
||||
0xA0, 0xA2, 0xA4, 0xA6, 0xA8, 0xAA, 0xAC, 0xAE, 0xB0, 0xB2, 0xB4, 0xB6, 0xB8, 0xBA, 0xBC, 0xBE,
|
||||
0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE, 0xD0, 0xD2, 0xD4, 0xD6, 0xD8, 0xDA, 0xDC, 0xDE,
|
||||
0xE0, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEC, 0xEE, 0xF0, 0xF2, 0xF4, 0xF6, 0xF8, 0xFA, 0xFC, 0xFE,
|
||||
0x1B, 0x19, 0x1F, 0x1D, 0x13, 0x11, 0x17, 0x15, 0x0B, 0x09, 0x0F, 0x0D, 0x03, 0x01, 0x07, 0x05,
|
||||
0x3B, 0x39, 0x3F, 0x3D, 0x33, 0x31, 0x37, 0x35, 0x2B, 0x29, 0x2F, 0x2D, 0x23, 0x21, 0x27, 0x25,
|
||||
0x5B, 0x59, 0x5F, 0x5D, 0x53, 0x51, 0x57, 0x55, 0x4B, 0x49, 0x4F, 0x4D, 0x43, 0x41, 0x47, 0x45,
|
||||
0x7B, 0x79, 0x7F, 0x7D, 0x73, 0x71, 0x77, 0x75, 0x6B, 0x69, 0x6F, 0x6D, 0x63, 0x61, 0x67, 0x65,
|
||||
0x9B, 0x99, 0x9F, 0x9D, 0x93, 0x91, 0x97, 0x95, 0x8B, 0x89, 0x8F, 0x8D, 0x83, 0x81, 0x87, 0x85,
|
||||
0xBB, 0xB9, 0xBF, 0xBD, 0xB3, 0xB1, 0xB7, 0xB5, 0xAB, 0xA9, 0xAF, 0xAD, 0xA3, 0xA1, 0xA7, 0xA5,
|
||||
0xDB, 0xD9, 0xDF, 0xDD, 0xD3, 0xD1, 0xD7, 0xD5, 0xCB, 0xC9, 0xCF, 0xCD, 0xC3, 0xC1, 0xC7, 0xC5,
|
||||
0xFB, 0xF9, 0xFF, 0xFD, 0xF3, 0xF1, 0xF7, 0xF5, 0xEB, 0xE9, 0xEF, 0xED, 0xE3, 0xE1, 0xE7, 0xE5
|
||||
};
|
||||
|
||||
const uint8_t accelc_aes_GF2p8_Mul_0x03[256] = {
|
||||
0x00, 0x03, 0x06, 0x05, 0x0C, 0x0F, 0x0A, 0x09, 0x18, 0x1B, 0x1E, 0x1D, 0x14, 0x17, 0x12, 0x11,
|
||||
0x30, 0x33, 0x36, 0x35, 0x3C, 0x3F, 0x3A, 0x39, 0x28, 0x2B, 0x2E, 0x2D, 0x24, 0x27, 0x22, 0x21,
|
||||
0x60, 0x63, 0x66, 0x65, 0x6C, 0x6F, 0x6A, 0x69, 0x78, 0x7B, 0x7E, 0x7D, 0x74, 0x77, 0x72, 0x71,
|
||||
0x50, 0x53, 0x56, 0x55, 0x5C, 0x5F, 0x5A, 0x59, 0x48, 0x4B, 0x4E, 0x4D, 0x44, 0x47, 0x42, 0x41,
|
||||
0xC0, 0xC3, 0xC6, 0xC5, 0xCC, 0xCF, 0xCA, 0xC9, 0xD8, 0xDB, 0xDE, 0xDD, 0xD4, 0xD7, 0xD2, 0xD1,
|
||||
0xF0, 0xF3, 0xF6, 0xF5, 0xFC, 0xFF, 0xFA, 0xF9, 0xE8, 0xEB, 0xEE, 0xED, 0xE4, 0xE7, 0xE2, 0xE1,
|
||||
0xA0, 0xA3, 0xA6, 0xA5, 0xAC, 0xAF, 0xAA, 0xA9, 0xB8, 0xBB, 0xBE, 0xBD, 0xB4, 0xB7, 0xB2, 0xB1,
|
||||
0x90, 0x93, 0x96, 0x95, 0x9C, 0x9F, 0x9A, 0x99, 0x88, 0x8B, 0x8E, 0x8D, 0x84, 0x87, 0x82, 0x81,
|
||||
0x9B, 0x98, 0x9D, 0x9E, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8F, 0x8C, 0x89, 0x8A,
|
||||
0xAB, 0xA8, 0xAD, 0xAE, 0xA7, 0xA4, 0xA1, 0xA2, 0xB3, 0xB0, 0xB5, 0xB6, 0xBF, 0xBC, 0xB9, 0xBA,
|
||||
0xFB, 0xF8, 0xFD, 0xFE, 0xF7, 0xF4, 0xF1, 0xF2, 0xE3, 0xE0, 0xE5, 0xE6, 0xEF, 0xEC, 0xE9, 0xEA,
|
||||
0xCB, 0xC8, 0xCD, 0xCE, 0xC7, 0xC4, 0xC1, 0xC2, 0xD3, 0xD0, 0xD5, 0xD6, 0xDF, 0xDC, 0xD9, 0xDA,
|
||||
0x5B, 0x58, 0x5D, 0x5E, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4F, 0x4C, 0x49, 0x4A,
|
||||
0x6B, 0x68, 0x6D, 0x6E, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7F, 0x7C, 0x79, 0x7A,
|
||||
0x3B, 0x38, 0x3D, 0x3E, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2F, 0x2C, 0x29, 0x2A,
|
||||
0x0B, 0x08, 0x0D, 0x0E, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1F, 0x1C, 0x19, 0x1A
|
||||
};
|
||||
|
||||
const uint8_t accelc_aes_InverseSBox[256] = {
|
||||
0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
|
||||
0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
|
||||
0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
|
||||
0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
|
||||
0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
|
||||
0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
|
||||
0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
|
||||
0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
|
||||
0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
|
||||
0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
|
||||
0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
|
||||
0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
|
||||
0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
|
||||
0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
|
||||
0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
|
||||
0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
|
||||
};
|
||||
|
||||
const uint8_t accelc_aes_GF2p8_Mul_0x09[256] = {
|
||||
0x00, 0x09, 0x12, 0x1B, 0x24, 0x2D, 0x36, 0x3F, 0x48, 0x41, 0x5A, 0x53, 0x6C, 0x65, 0x7E, 0x77,
|
||||
0x90, 0x99, 0x82, 0x8B, 0xB4, 0xBD, 0xA6, 0xAF, 0xD8, 0xD1, 0xCA, 0xC3, 0xFC, 0xF5, 0xEE, 0xE7,
|
||||
0x3B, 0x32, 0x29, 0x20, 0x1F, 0x16, 0x0D, 0x04, 0x73, 0x7A, 0x61, 0x68, 0x57, 0x5E, 0x45, 0x4C,
|
||||
0xAB, 0xA2, 0xB9, 0xB0, 0x8F, 0x86, 0x9D, 0x94, 0xE3, 0xEA, 0xF1, 0xF8, 0xC7, 0xCE, 0xD5, 0xDC,
|
||||
0x76, 0x7F, 0x64, 0x6D, 0x52, 0x5B, 0x40, 0x49, 0x3E, 0x37, 0x2C, 0x25, 0x1A, 0x13, 0x08, 0x01,
|
||||
0xE6, 0xEF, 0xF4, 0xFD, 0xC2, 0xCB, 0xD0, 0xD9, 0xAE, 0xA7, 0xBC, 0xB5, 0x8A, 0x83, 0x98, 0x91,
|
||||
0x4D, 0x44, 0x5F, 0x56, 0x69, 0x60, 0x7B, 0x72, 0x05, 0x0C, 0x17, 0x1E, 0x21, 0x28, 0x33, 0x3A,
|
||||
0xDD, 0xD4, 0xCF, 0xC6, 0xF9, 0xF0, 0xEB, 0xE2, 0x95, 0x9C, 0x87, 0x8E, 0xB1, 0xB8, 0xA3, 0xAA,
|
||||
0xEC, 0xE5, 0xFE, 0xF7, 0xC8, 0xC1, 0xDA, 0xD3, 0xA4, 0xAD, 0xB6, 0xBF, 0x80, 0x89, 0x92, 0x9B,
|
||||
0x7C, 0x75, 0x6E, 0x67, 0x58, 0x51, 0x4A, 0x43, 0x34, 0x3D, 0x26, 0x2F, 0x10, 0x19, 0x02, 0x0B,
|
||||
0xD7, 0xDE, 0xC5, 0xCC, 0xF3, 0xFA, 0xE1, 0xE8, 0x9F, 0x96, 0x8D, 0x84, 0xBB, 0xB2, 0xA9, 0xA0,
|
||||
0x47, 0x4E, 0x55, 0x5C, 0x63, 0x6A, 0x71, 0x78, 0x0F, 0x06, 0x1D, 0x14, 0x2B, 0x22, 0x39, 0x30,
|
||||
0x9A, 0x93, 0x88, 0x81, 0xBE, 0xB7, 0xAC, 0xA5, 0xD2, 0xDB, 0xC0, 0xC9, 0xF6, 0xFF, 0xE4, 0xED,
|
||||
0x0A, 0x03, 0x18, 0x11, 0x2E, 0x27, 0x3C, 0x35, 0x42, 0x4B, 0x50, 0x59, 0x66, 0x6F, 0x74, 0x7D,
|
||||
0xA1, 0xA8, 0xB3, 0xBA, 0x85, 0x8C, 0x97, 0x9E, 0xE9, 0xE0, 0xFB, 0xF2, 0xCD, 0xC4, 0xDF, 0xD6,
|
||||
0x31, 0x38, 0x23, 0x2A, 0x15, 0x1C, 0x07, 0x0E, 0x79, 0x70, 0x6B, 0x62, 0x5D, 0x54, 0x4F, 0x46
|
||||
};
|
||||
|
||||
const uint8_t accelc_aes_GF2p8_Mul_0x0B[256] = {
|
||||
0x00, 0x0B, 0x16, 0x1D, 0x2C, 0x27, 0x3A, 0x31, 0x58, 0x53, 0x4E, 0x45, 0x74, 0x7F, 0x62, 0x69,
|
||||
0xB0, 0xBB, 0xA6, 0xAD, 0x9C, 0x97, 0x8A, 0x81, 0xE8, 0xE3, 0xFE, 0xF5, 0xC4, 0xCF, 0xD2, 0xD9,
|
||||
0x7B, 0x70, 0x6D, 0x66, 0x57, 0x5C, 0x41, 0x4A, 0x23, 0x28, 0x35, 0x3E, 0x0F, 0x04, 0x19, 0x12,
|
||||
0xCB, 0xC0, 0xDD, 0xD6, 0xE7, 0xEC, 0xF1, 0xFA, 0x93, 0x98, 0x85, 0x8E, 0xBF, 0xB4, 0xA9, 0xA2,
|
||||
0xF6, 0xFD, 0xE0, 0xEB, 0xDA, 0xD1, 0xCC, 0xC7, 0xAE, 0xA5, 0xB8, 0xB3, 0x82, 0x89, 0x94, 0x9F,
|
||||
0x46, 0x4D, 0x50, 0x5B, 0x6A, 0x61, 0x7C, 0x77, 0x1E, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2F,
|
||||
0x8D, 0x86, 0x9B, 0x90, 0xA1, 0xAA, 0xB7, 0xBC, 0xD5, 0xDE, 0xC3, 0xC8, 0xF9, 0xF2, 0xEF, 0xE4,
|
||||
0x3D, 0x36, 0x2B, 0x20, 0x11, 0x1A, 0x07, 0x0C, 0x65, 0x6E, 0x73, 0x78, 0x49, 0x42, 0x5F, 0x54,
|
||||
0xF7, 0xFC, 0xE1, 0xEA, 0xDB, 0xD0, 0xCD, 0xC6, 0xAF, 0xA4, 0xB9, 0xB2, 0x83, 0x88, 0x95, 0x9E,
|
||||
0x47, 0x4C, 0x51, 0x5A, 0x6B, 0x60, 0x7D, 0x76, 0x1F, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2E,
|
||||
0x8C, 0x87, 0x9A, 0x91, 0xA0, 0xAB, 0xB6, 0xBD, 0xD4, 0xDF, 0xC2, 0xC9, 0xF8, 0xF3, 0xEE, 0xE5,
|
||||
0x3C, 0x37, 0x2A, 0x21, 0x10, 0x1B, 0x06, 0x0D, 0x64, 0x6F, 0x72, 0x79, 0x48, 0x43, 0x5E, 0x55,
|
||||
0x01, 0x0A, 0x17, 0x1C, 0x2D, 0x26, 0x3B, 0x30, 0x59, 0x52, 0x4F, 0x44, 0x75, 0x7E, 0x63, 0x68,
|
||||
0xB1, 0xBA, 0xA7, 0xAC, 0x9D, 0x96, 0x8B, 0x80, 0xE9, 0xE2, 0xFF, 0xF4, 0xC5, 0xCE, 0xD3, 0xD8,
|
||||
0x7A, 0x71, 0x6C, 0x67, 0x56, 0x5D, 0x40, 0x4B, 0x22, 0x29, 0x34, 0x3F, 0x0E, 0x05, 0x18, 0x13,
|
||||
0xCA, 0xC1, 0xDC, 0xD7, 0xE6, 0xED, 0xF0, 0xFB, 0x92, 0x99, 0x84, 0x8F, 0xBE, 0xB5, 0xA8, 0xA3
|
||||
};
|
||||
|
||||
const uint8_t accelc_aes_GF2p8_Mul_0x0D[256] = {
|
||||
0x00, 0x0D, 0x1A, 0x17, 0x34, 0x39, 0x2E, 0x23, 0x68, 0x65, 0x72, 0x7F, 0x5C, 0x51, 0x46, 0x4B,
|
||||
0xD0, 0xDD, 0xCA, 0xC7, 0xE4, 0xE9, 0xFE, 0xF3, 0xB8, 0xB5, 0xA2, 0xAF, 0x8C, 0x81, 0x96, 0x9B,
|
||||
0xBB, 0xB6, 0xA1, 0xAC, 0x8F, 0x82, 0x95, 0x98, 0xD3, 0xDE, 0xC9, 0xC4, 0xE7, 0xEA, 0xFD, 0xF0,
|
||||
0x6B, 0x66, 0x71, 0x7C, 0x5F, 0x52, 0x45, 0x48, 0x03, 0x0E, 0x19, 0x14, 0x37, 0x3A, 0x2D, 0x20,
|
||||
0x6D, 0x60, 0x77, 0x7A, 0x59, 0x54, 0x43, 0x4E, 0x05, 0x08, 0x1F, 0x12, 0x31, 0x3C, 0x2B, 0x26,
|
||||
0xBD, 0xB0, 0xA7, 0xAA, 0x89, 0x84, 0x93, 0x9E, 0xD5, 0xD8, 0xCF, 0xC2, 0xE1, 0xEC, 0xFB, 0xF6,
|
||||
0xD6, 0xDB, 0xCC, 0xC1, 0xE2, 0xEF, 0xF8, 0xF5, 0xBE, 0xB3, 0xA4, 0xA9, 0x8A, 0x87, 0x90, 0x9D,
|
||||
0x06, 0x0B, 0x1C, 0x11, 0x32, 0x3F, 0x28, 0x25, 0x6E, 0x63, 0x74, 0x79, 0x5A, 0x57, 0x40, 0x4D,
|
||||
0xDA, 0xD7, 0xC0, 0xCD, 0xEE, 0xE3, 0xF4, 0xF9, 0xB2, 0xBF, 0xA8, 0xA5, 0x86, 0x8B, 0x9C, 0x91,
|
||||
0x0A, 0x07, 0x10, 0x1D, 0x3E, 0x33, 0x24, 0x29, 0x62, 0x6F, 0x78, 0x75, 0x56, 0x5B, 0x4C, 0x41,
|
||||
0x61, 0x6C, 0x7B, 0x76, 0x55, 0x58, 0x4F, 0x42, 0x09, 0x04, 0x13, 0x1E, 0x3D, 0x30, 0x27, 0x2A,
|
||||
0xB1, 0xBC, 0xAB, 0xA6, 0x85, 0x88, 0x9F, 0x92, 0xD9, 0xD4, 0xC3, 0xCE, 0xED, 0xE0, 0xF7, 0xFA,
|
||||
0xB7, 0xBA, 0xAD, 0xA0, 0x83, 0x8E, 0x99, 0x94, 0xDF, 0xD2, 0xC5, 0xC8, 0xEB, 0xE6, 0xF1, 0xFC,
|
||||
0x67, 0x6A, 0x7D, 0x70, 0x53, 0x5E, 0x49, 0x44, 0x0F, 0x02, 0x15, 0x18, 0x3B, 0x36, 0x21, 0x2C,
|
||||
0x0C, 0x01, 0x16, 0x1B, 0x38, 0x35, 0x22, 0x2F, 0x64, 0x69, 0x7E, 0x73, 0x50, 0x5D, 0x4A, 0x47,
|
||||
0xDC, 0xD1, 0xC6, 0xCB, 0xE8, 0xE5, 0xF2, 0xFF, 0xB4, 0xB9, 0xAE, 0xA3, 0x80, 0x8D, 0x9A, 0x97
|
||||
};
|
||||
|
||||
const uint8_t accelc_aes_GF2p8_Mul_0x0E[256] = {
|
||||
0x00, 0x0E, 0x1C, 0x12, 0x38, 0x36, 0x24, 0x2A, 0x70, 0x7E, 0x6C, 0x62, 0x48, 0x46, 0x54, 0x5A,
|
||||
0xE0, 0xEE, 0xFC, 0xF2, 0xD8, 0xD6, 0xC4, 0xCA, 0x90, 0x9E, 0x8C, 0x82, 0xA8, 0xA6, 0xB4, 0xBA,
|
||||
0xDB, 0xD5, 0xC7, 0xC9, 0xE3, 0xED, 0xFF, 0xF1, 0xAB, 0xA5, 0xB7, 0xB9, 0x93, 0x9D, 0x8F, 0x81,
|
||||
0x3B, 0x35, 0x27, 0x29, 0x03, 0x0D, 0x1F, 0x11, 0x4B, 0x45, 0x57, 0x59, 0x73, 0x7D, 0x6F, 0x61,
|
||||
0xAD, 0xA3, 0xB1, 0xBF, 0x95, 0x9B, 0x89, 0x87, 0xDD, 0xD3, 0xC1, 0xCF, 0xE5, 0xEB, 0xF9, 0xF7,
|
||||
0x4D, 0x43, 0x51, 0x5F, 0x75, 0x7B, 0x69, 0x67, 0x3D, 0x33, 0x21, 0x2F, 0x05, 0x0B, 0x19, 0x17,
|
||||
0x76, 0x78, 0x6A, 0x64, 0x4E, 0x40, 0x52, 0x5C, 0x06, 0x08, 0x1A, 0x14, 0x3E, 0x30, 0x22, 0x2C,
|
||||
0x96, 0x98, 0x8A, 0x84, 0xAE, 0xA0, 0xB2, 0xBC, 0xE6, 0xE8, 0xFA, 0xF4, 0xDE, 0xD0, 0xC2, 0xCC,
|
||||
0x41, 0x4F, 0x5D, 0x53, 0x79, 0x77, 0x65, 0x6B, 0x31, 0x3F, 0x2D, 0x23, 0x09, 0x07, 0x15, 0x1B,
|
||||
0xA1, 0xAF, 0xBD, 0xB3, 0x99, 0x97, 0x85, 0x8B, 0xD1, 0xDF, 0xCD, 0xC3, 0xE9, 0xE7, 0xF5, 0xFB,
|
||||
0x9A, 0x94, 0x86, 0x88, 0xA2, 0xAC, 0xBE, 0xB0, 0xEA, 0xE4, 0xF6, 0xF8, 0xD2, 0xDC, 0xCE, 0xC0,
|
||||
0x7A, 0x74, 0x66, 0x68, 0x42, 0x4C, 0x5E, 0x50, 0x0A, 0x04, 0x16, 0x18, 0x32, 0x3C, 0x2E, 0x20,
|
||||
0xEC, 0xE2, 0xF0, 0xFE, 0xD4, 0xDA, 0xC8, 0xC6, 0x9C, 0x92, 0x80, 0x8E, 0xA4, 0xAA, 0xB8, 0xB6,
|
||||
0x0C, 0x02, 0x10, 0x1E, 0x34, 0x3A, 0x28, 0x26, 0x7C, 0x72, 0x60, 0x6E, 0x44, 0x4A, 0x58, 0x56,
|
||||
0x37, 0x39, 0x2B, 0x25, 0x0F, 0x01, 0x13, 0x1D, 0x47, 0x49, 0x5B, 0x55, 0x7F, 0x71, 0x63, 0x6D,
|
||||
0xD7, 0xD9, 0xCB, 0xC5, 0xEF, 0xE1, 0xF3, 0xFD, 0xA7, 0xA9, 0xBB, 0xB5, 0x9F, 0x91, 0x83, 0x8D
|
||||
};
|
||||
@@ -1,281 +0,0 @@
|
||||
#include "blowfish.h"
|
||||
#include <memory.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include <intrin.h>
|
||||
#define _bswap _byteswap_ulong
|
||||
#elif defined(__GNUC__)
|
||||
#include <x86intrin.h>
|
||||
#endif
|
||||
|
||||
const uint32_t accelc_Blowfish_Original_PBox[18] = {
|
||||
0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, 0xA4093822, 0x299F31D0,
|
||||
0x082EFA98, 0xEC4E6C89, 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,
|
||||
0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917, 0x9216D5D9, 0x8979FB1B
|
||||
};
|
||||
|
||||
const uint32_t accelc_Blowfish_Original_SBox[4][256] = {
|
||||
{
|
||||
0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, 0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99, 0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16, 0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E,
|
||||
0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE, 0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013, 0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF, 0x8E79DCB0, 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E,
|
||||
0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60, 0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440, 0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE, 0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A,
|
||||
0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E, 0xAFD6BA33, 0x6C24CF5C, 0x7A325381, 0x28958677, 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193, 0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032,
|
||||
0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88, 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239, 0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E, 0x21C66842, 0xF6E96C9A, 0x670C9C61, 0xABD388F0,
|
||||
0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3, 0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98, 0xA1F1651D, 0x39AF0176, 0x66CA593E, 0x82430E88, 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE,
|
||||
0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6, 0x4ED3AA62, 0x363F7706, 0x1BFEDF72, 0x429B023D, 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B, 0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7,
|
||||
0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA, 0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463, 0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F, 0x6DFC511F, 0x9B30952C, 0xCC814544, 0xAF5EBD09,
|
||||
0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3, 0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB, 0x5579C0BD, 0x1A60320A, 0xD6A100C6, 0x402C7279, 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8,
|
||||
0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB, 0x323DB5FA, 0xFD238760, 0x53317B48, 0x3E00DF82, 0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB, 0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573,
|
||||
0x695B27B0, 0xBBCA58C8, 0xE1FFA35D, 0xB8F011A0, 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B, 0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790, 0xE1DDF2DA, 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8,
|
||||
0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4, 0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0, 0xD08ED1D0, 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7, 0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C,
|
||||
0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD, 0x2F2F2218, 0xBE0E1777, 0xEA752DFE, 0x8B021FA1, 0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299, 0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9,
|
||||
0x165FA266, 0x80957705, 0x93CC7314, 0x211A1477, 0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF, 0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49, 0x00250E2D, 0x2071B35E, 0x226800BB, 0x57B8E0AF,
|
||||
0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA, 0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5, 0x83260376, 0x6295CFA9, 0x11C81968, 0x4E734A41, 0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915,
|
||||
0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400, 0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915, 0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664, 0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A
|
||||
},
|
||||
|
||||
{
|
||||
0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623, 0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266, 0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1, 0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E,
|
||||
0x3F54989A, 0x5B429D65, 0x6B8FE4D6, 0x99F73FD6, 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1, 0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E, 0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1,
|
||||
0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737, 0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8, 0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF, 0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD,
|
||||
0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701, 0x3AE5E581, 0x37C2DADC, 0xC8B57634, 0x9AF3DDA7, 0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41, 0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331,
|
||||
0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF, 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF, 0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E, 0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87,
|
||||
0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C, 0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2, 0xEF1C1847, 0x3215D908, 0xDD433B37, 0x24C2BA16, 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD,
|
||||
0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B, 0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509, 0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E, 0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3,
|
||||
0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F, 0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A, 0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4, 0xF2F74EA7, 0x361D2B3D, 0x1939260F, 0x19C27960,
|
||||
0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66, 0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28, 0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802, 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84,
|
||||
0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510, 0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF, 0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14, 0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E,
|
||||
0x648B1EAF, 0x19BDF0CA, 0xA02369B9, 0x655ABB50, 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7, 0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8, 0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281,
|
||||
0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99, 0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696, 0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128, 0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73,
|
||||
0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0, 0x45EEE2B6, 0xA3AAABEA, 0xDB6C4F15, 0xFACB4FD0, 0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105, 0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250,
|
||||
0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3, 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285, 0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00, 0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061,
|
||||
0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB, 0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E, 0xA6078084, 0x19F8509E, 0xE8EFD855, 0x61D99735, 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC,
|
||||
0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9, 0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340, 0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20, 0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7
|
||||
},
|
||||
|
||||
{
|
||||
0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934, 0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068, 0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF, 0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840,
|
||||
0x4D95FC1D, 0x96B591AF, 0x70F4DDD3, 0x66A02F45, 0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504, 0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A, 0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB,
|
||||
0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE, 0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6, 0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42, 0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B,
|
||||
0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2, 0x3A6EFA74, 0xDD5B4332, 0x6841E7F7, 0xCA7820FB, 0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527, 0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B,
|
||||
0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33, 0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C, 0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3, 0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC,
|
||||
0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17, 0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564, 0x257B7834, 0x602A9C60, 0xDFF8E8A3, 0x1F636C1B, 0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115,
|
||||
0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922, 0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728, 0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0, 0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E,
|
||||
0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37, 0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D, 0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804, 0xF1290DC7, 0xCC00FFA3, 0xB5390F92, 0x690FED0B,
|
||||
0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3, 0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB, 0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D, 0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C,
|
||||
0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350, 0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9, 0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A, 0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE,
|
||||
0x9DBC8057, 0xF0F7C086, 0x60787BF8, 0x6003604D, 0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC, 0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F, 0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61,
|
||||
0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2, 0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9, 0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2, 0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C,
|
||||
0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E, 0xB77F19B6, 0xE0A9DC09, 0x662D09A1, 0xC4324633, 0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10, 0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169,
|
||||
0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52, 0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027, 0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5, 0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62,
|
||||
0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634, 0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76, 0x6F05E409, 0x4B7C0188, 0x39720A3D, 0x7C927C24, 0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC,
|
||||
0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4, 0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C, 0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837, 0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0
|
||||
},
|
||||
|
||||
{
|
||||
0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B, 0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE, 0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B, 0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4,
|
||||
0x5748AB2F, 0xBC946E79, 0xC6A376D2, 0x6549C2C8, 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6, 0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304, 0xA1FAD5F0, 0x6A2D519A, 0x63EF8CE2, 0x9A86EE22,
|
||||
0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4, 0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6, 0x2826A2F9, 0xA73A3AE1, 0x4BA99586, 0xEF5562E9, 0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59,
|
||||
0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593, 0xE990FD5A, 0x9E34D797, 0x2CF0B7D9, 0x022B8B51, 0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28, 0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C,
|
||||
0xE029AC71, 0xE019A5E6, 0x47B0ACFD, 0xED93FA9B, 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28, 0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C, 0x15056DD4, 0x88F46DBA, 0x03A16125, 0x0564F0BD,
|
||||
0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A, 0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319, 0x7533D928, 0xB155FDF5, 0x03563482, 0x8ABA3CBB, 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F,
|
||||
0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991, 0xEA7A90C2, 0xFB3E7BCE, 0x5121CE64, 0x774FBE32, 0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680, 0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166,
|
||||
0xB39A460A, 0x6445C0DD, 0x586CDECF, 0x1C20C8AE, 0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB, 0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5, 0x72EACEA8, 0xFA6484BB, 0x8D6612AE, 0xBF3C6F47,
|
||||
0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370, 0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D, 0x4040CB08, 0x4EB4E2CC, 0x34D2466A, 0x0115AF84, 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048,
|
||||
0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8, 0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD, 0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9, 0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7,
|
||||
0x1A908749, 0xD44FBD9A, 0xD0DADECB, 0xD50ADA38, 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F, 0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C, 0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525,
|
||||
0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1, 0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442, 0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964, 0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E,
|
||||
0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8, 0xDF359F8D, 0x9B992F2E, 0xE60B6F47, 0x0FE3F11D, 0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F, 0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299,
|
||||
0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02, 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC, 0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614, 0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A,
|
||||
0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6, 0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B, 0x53113EC0, 0x1640E3D3, 0x38ABBD60, 0x2547ADF0, 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060,
|
||||
0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E, 0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9, 0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F, 0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6
|
||||
}
|
||||
};
|
||||
|
||||
#define f_transform(_x, _S) ((((_S)[0][(_x)[3]] + (_S)[1][(_x)[2]]) ^ (_S)[2][(_x)[1]]) + (_S)[3][(_x)[0]])
|
||||
|
||||
void accelc_Blowfish_encrypt(uint8_t srcBytes[8],
|
||||
const BLOWFISH_KEY* srcKey,
|
||||
int Endian) {
|
||||
uint32_t* const L = (uint32_t*)srcBytes;
|
||||
uint32_t* const R = (uint32_t*)(srcBytes + 4);
|
||||
|
||||
if (Endian == BLOWFISH_BIG_ENDIAN) {
|
||||
*L = _bswap(*L);
|
||||
*R = _bswap(*R);
|
||||
}
|
||||
|
||||
*L ^= srcKey->SubKey[0];
|
||||
*R ^= f_transform(srcBytes, srcKey->SBox);
|
||||
|
||||
*R ^= srcKey->SubKey[1];
|
||||
*L ^= f_transform(srcBytes + 4, srcKey->SBox);
|
||||
|
||||
*L ^= srcKey->SubKey[2];
|
||||
*R ^= f_transform(srcBytes, srcKey->SBox);
|
||||
|
||||
*R ^= srcKey->SubKey[3];
|
||||
*L ^= f_transform(srcBytes + 4, srcKey->SBox);
|
||||
|
||||
*L ^= srcKey->SubKey[4];
|
||||
*R ^= f_transform(srcBytes, srcKey->SBox);
|
||||
|
||||
*R ^= srcKey->SubKey[5];
|
||||
*L ^= f_transform(srcBytes + 4, srcKey->SBox);
|
||||
|
||||
*L ^= srcKey->SubKey[6];
|
||||
*R ^= f_transform(srcBytes, srcKey->SBox);
|
||||
|
||||
*R ^= srcKey->SubKey[7];
|
||||
*L ^= f_transform(srcBytes + 4, srcKey->SBox);
|
||||
|
||||
*L ^= srcKey->SubKey[8];
|
||||
*R ^= f_transform(srcBytes, srcKey->SBox);
|
||||
|
||||
*R ^= srcKey->SubKey[9];
|
||||
*L ^= f_transform(srcBytes + 4, srcKey->SBox);
|
||||
|
||||
*L ^= srcKey->SubKey[10];
|
||||
*R ^= f_transform(srcBytes, srcKey->SBox);
|
||||
|
||||
*R ^= srcKey->SubKey[11];
|
||||
*L ^= f_transform(srcBytes + 4, srcKey->SBox);
|
||||
|
||||
*L ^= srcKey->SubKey[12];
|
||||
*R ^= f_transform(srcBytes, srcKey->SBox);
|
||||
|
||||
*R ^= srcKey->SubKey[13];
|
||||
*L ^= f_transform(srcBytes + 4, srcKey->SBox);
|
||||
|
||||
*L ^= srcKey->SubKey[14];
|
||||
*R ^= f_transform(srcBytes, srcKey->SBox);
|
||||
|
||||
*R ^= srcKey->SubKey[15];
|
||||
*L ^= f_transform(srcBytes + 4, srcKey->SBox);
|
||||
|
||||
*L ^= srcKey->SubKey[16];
|
||||
*R ^= srcKey->SubKey[17];
|
||||
|
||||
uint32_t temp = *R;
|
||||
*R = *L;
|
||||
*L = temp;
|
||||
|
||||
if (Endian == BLOWFISH_BIG_ENDIAN) {
|
||||
*L = _bswap(*L);
|
||||
*R = _bswap(*R);
|
||||
}
|
||||
}
|
||||
|
||||
void accelc_Blowfish_decrypt(uint8_t srcBytes[8],
|
||||
const BLOWFISH_KEY* srcKey,
|
||||
int Endian) {
|
||||
uint32_t* const L = (uint32_t*)srcBytes;
|
||||
uint32_t* const R = (uint32_t*)(srcBytes + 4);
|
||||
|
||||
if (Endian == BLOWFISH_BIG_ENDIAN) {
|
||||
*L = _bswap(*L);
|
||||
*R = _bswap(*R);
|
||||
}
|
||||
|
||||
uint32_t temp = *R;
|
||||
*R = *L;
|
||||
*L = temp;
|
||||
|
||||
*L ^= srcKey->SubKey[16];
|
||||
*R ^= srcKey->SubKey[17];
|
||||
|
||||
*L ^= f_transform(srcBytes + 4, srcKey->SBox);
|
||||
*R ^= srcKey->SubKey[15];
|
||||
|
||||
*R ^= f_transform(srcBytes, srcKey->SBox);
|
||||
*L ^= srcKey->SubKey[14];
|
||||
|
||||
*L ^= f_transform(srcBytes + 4, srcKey->SBox);
|
||||
*R ^= srcKey->SubKey[13];
|
||||
|
||||
*R ^= f_transform(srcBytes, srcKey->SBox);
|
||||
*L ^= srcKey->SubKey[12];
|
||||
|
||||
*L ^= f_transform(srcBytes + 4, srcKey->SBox);
|
||||
*R ^= srcKey->SubKey[11];
|
||||
|
||||
*R ^= f_transform(srcBytes, srcKey->SBox);
|
||||
*L ^= srcKey->SubKey[10];
|
||||
|
||||
*L ^= f_transform(srcBytes + 4, srcKey->SBox);
|
||||
*R ^= srcKey->SubKey[9];
|
||||
|
||||
*R ^= f_transform(srcBytes, srcKey->SBox);
|
||||
*L ^= srcKey->SubKey[8];
|
||||
|
||||
*L ^= f_transform(srcBytes + 4, srcKey->SBox);
|
||||
*R ^= srcKey->SubKey[7];
|
||||
|
||||
*R ^= f_transform(srcBytes, srcKey->SBox);
|
||||
*L ^= srcKey->SubKey[6];
|
||||
|
||||
*L ^= f_transform(srcBytes + 4, srcKey->SBox);
|
||||
*R ^= srcKey->SubKey[5];
|
||||
|
||||
*R ^= f_transform(srcBytes, srcKey->SBox);
|
||||
*L ^= srcKey->SubKey[4];
|
||||
|
||||
*L ^= f_transform(srcBytes + 4, srcKey->SBox);
|
||||
*R ^= srcKey->SubKey[3];
|
||||
|
||||
*R ^= f_transform(srcBytes, srcKey->SBox);
|
||||
*L ^= srcKey->SubKey[2];
|
||||
|
||||
*L ^= f_transform(srcBytes + 4, srcKey->SBox);
|
||||
*R ^= srcKey->SubKey[1];
|
||||
|
||||
*R ^= f_transform(srcBytes, srcKey->SBox);
|
||||
*L ^= srcKey->SubKey[0];
|
||||
|
||||
if (Endian == BLOWFISH_BIG_ENDIAN) {
|
||||
*L = _bswap(*L);
|
||||
*R = _bswap(*R);
|
||||
}
|
||||
}
|
||||
|
||||
int accelc_Blowfish_set_key(const uint8_t srcUserKey[], uint8_t UserKeyLength,
|
||||
BLOWFISH_KEY* dstKey) {
|
||||
if (UserKeyLength == 0)
|
||||
return STATUS_BLOWFISH_INVALID_KEY_LENGTH;
|
||||
if (UserKeyLength > BLOWFISH_MAX_KEY_LENGTH)
|
||||
return STATUS_BLOWFISH_KEY_TOO_LONG;
|
||||
|
||||
memcpy(dstKey->SubKey, accelc_Blowfish_Original_PBox, sizeof(accelc_Blowfish_Original_PBox));
|
||||
memcpy(dstKey->SBox, accelc_Blowfish_Original_SBox, sizeof(accelc_Blowfish_Original_SBox));
|
||||
|
||||
for (int i = 0; i < 18; ++i) {
|
||||
uint32_t temp = 0;
|
||||
|
||||
temp <<= 8;
|
||||
temp |= srcUserKey[(i * 4) % UserKeyLength];
|
||||
|
||||
temp <<= 8;
|
||||
temp |= srcUserKey[(i * 4 + 1) % UserKeyLength];
|
||||
|
||||
temp <<= 8;
|
||||
temp |= srcUserKey[(i * 4 + 2) % UserKeyLength];
|
||||
|
||||
temp <<= 8;
|
||||
temp |= srcUserKey[(i * 4 + 3) % UserKeyLength];
|
||||
|
||||
dstKey->SubKey[i] ^= temp;
|
||||
}
|
||||
|
||||
uint8_t temp[8] = { 0 };
|
||||
for (int i = 0; i < 9; ++i) {
|
||||
accelc_Blowfish_encrypt(temp, dstKey, BLOWFISH_LITTLE_ENDIAN);
|
||||
((uint64_t*)dstKey->SubKey)[i] = *(uint64_t*)temp;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 512; ++i) {
|
||||
accelc_Blowfish_encrypt(temp, dstKey, BLOWFISH_LITTLE_ENDIAN);
|
||||
((uint64_t*)dstKey->SBox)[i] = *(uint64_t*)temp;
|
||||
}
|
||||
|
||||
return STATUS_BLOWFISH_SUCCESS;
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#define STATUS_BLOWFISH_SUCCESS 0
|
||||
#define STATUS_BLOWFISH_INVALID_KEY_LENGTH (-1)
|
||||
#define STATUS_BLOWFISH_KEY_TOO_LONG (-2)
|
||||
|
||||
#define BLOWFISH_LITTLE_ENDIAN 0
|
||||
#define BLOWFISH_BIG_ENDIAN 1
|
||||
|
||||
#define BLOWFISH_MIN_KEY_LENGTH 1
|
||||
#define BLOWFISH_MAX_KEY_LENGTH 56
|
||||
|
||||
#define BLOWFISH_BLOCK_SIZE 8
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct _BLOWFISH_KEY {
|
||||
uint32_t SubKey[18];
|
||||
uint32_t SBox[4][256];
|
||||
} BLOWFISH_KEY;
|
||||
|
||||
void accelc_Blowfish_encrypt(uint8_t srcBytes[8],
|
||||
const BLOWFISH_KEY* srcKey,
|
||||
int Endian);
|
||||
|
||||
void accelc_Blowfish_decrypt(uint8_t srcBytes[8],
|
||||
const BLOWFISH_KEY* srcKey,
|
||||
int Endian);
|
||||
|
||||
int accelc_Blowfish_set_key(const uint8_t srcUserKey[], uint8_t UserKeyLength,
|
||||
BLOWFISH_KEY* dstKey);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
@@ -1,120 +0,0 @@
|
||||
#include "sha1.h"
|
||||
#include <memory.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include <intrin.h>
|
||||
#define _bswap _byteswap_ulong
|
||||
#define _bswap64 _byteswap_uint64
|
||||
#elif defined(__GNUC__)
|
||||
#include <x86intrin.h>
|
||||
#endif
|
||||
|
||||
#define SHA1_BLOCKSIZE 64
|
||||
|
||||
void accelc_SHA1_init(SHA1_BUFFER* HashBuffer) {
|
||||
HashBuffer->dword[0] = 0x67452301;
|
||||
HashBuffer->dword[1] = 0xEFCDAB89;
|
||||
HashBuffer->dword[2] = 0x98BADCFE;
|
||||
HashBuffer->dword[3] = 0x10325476;
|
||||
HashBuffer->dword[4] = 0xC3D2E1F0;
|
||||
}
|
||||
|
||||
void accelc_SHA1_update(const void* __restrict srcBytes, size_t srcBytesLength,
|
||||
SHA1_BUFFER* __restrict HashBuffer) {
|
||||
uint32_t Buffer[80] = { 0 };
|
||||
uint32_t a, b, c, d, e;
|
||||
const uint32_t (*MessageBlock)[16] = srcBytes;
|
||||
|
||||
size_t RoundsOfMainCycle = srcBytesLength / SHA1_BLOCKSIZE;
|
||||
for (size_t i = 0; i < RoundsOfMainCycle; ++i) {
|
||||
|
||||
for (int j = 0; j < 16; ++j)
|
||||
Buffer[j] = _bswap(MessageBlock[i][j]);
|
||||
|
||||
for (int j = 16; j < 80; ++j) {
|
||||
uint32_t temp = Buffer[j - 3] ^ Buffer[j - 8] ^ Buffer[j - 14] ^ Buffer[j - 16];
|
||||
Buffer[j] = _rotl(temp, 1);
|
||||
}
|
||||
a = HashBuffer->dword[0];
|
||||
b = HashBuffer->dword[1];
|
||||
c = HashBuffer->dword[2];
|
||||
d = HashBuffer->dword[3];
|
||||
e = HashBuffer->dword[4];
|
||||
|
||||
for (int j = 0; j < 20; ++j) {
|
||||
uint32_t T = _rotl(a, 5);
|
||||
T += ((b & c) ^ (~b & d)) + e + 0x5A827999 + Buffer[j];
|
||||
e = d;
|
||||
d = c;
|
||||
c = _rotl(b, 30);
|
||||
b = a;
|
||||
a = T;
|
||||
}
|
||||
for (int j = 20; j < 40; ++j) {
|
||||
uint32_t T = _rotl(a, 5);
|
||||
T += (b ^ c ^ d) + e + 0x6ED9EBA1 + Buffer[j];
|
||||
e = d;
|
||||
d = c;
|
||||
c = _rotl(b, 30);
|
||||
b = a;
|
||||
a = T;
|
||||
}
|
||||
for (int j = 40; j < 60; ++j) {
|
||||
uint32_t T = _rotl(a, 5);
|
||||
T += ((b & c) ^ (b & d) ^ (c & d)) + e + 0x8F1BBCDC + Buffer[j];
|
||||
e = d;
|
||||
d = c;
|
||||
c = _rotl(b, 30);
|
||||
b = a;
|
||||
a = T;
|
||||
}
|
||||
for (int j = 60; j < 80; ++j) {
|
||||
uint32_t T = _rotl(a, 5);
|
||||
T += (b ^ c ^ d) + e + 0xCA62C1D6 + Buffer[j];
|
||||
e = d;
|
||||
d = c;
|
||||
c = _rotl(b, 30);
|
||||
b = a;
|
||||
a = T;
|
||||
}
|
||||
HashBuffer->dword[0] += a;
|
||||
HashBuffer->dword[1] += b;
|
||||
HashBuffer->dword[2] += c;
|
||||
HashBuffer->dword[3] += d;
|
||||
HashBuffer->dword[4] += e;
|
||||
}
|
||||
}
|
||||
|
||||
void accelc_SHA1_final(const void* __restrict LeftBytes, size_t LeftBytesLength, uint64_t TotalBytesLength,
|
||||
const SHA1_BUFFER* HashBuffer, SHA1_DIGEST* Hash) {
|
||||
if (HashBuffer != Hash)
|
||||
memcpy(Hash, HashBuffer, sizeof(SHA1_BUFFER));
|
||||
|
||||
if (LeftBytesLength >= SHA1_BLOCKSIZE) {
|
||||
accelc_SHA1_update(LeftBytes, LeftBytesLength, Hash);
|
||||
LeftBytes = (const uint8_t*)LeftBytes + (LeftBytesLength / SHA1_BLOCKSIZE) * SHA1_BLOCKSIZE;
|
||||
LeftBytesLength %= SHA1_BLOCKSIZE;
|
||||
}
|
||||
|
||||
uint8_t Extra[128] = { 0 };
|
||||
for (size_t i = 0; i < LeftBytesLength; ++i)
|
||||
Extra[i] = ((const uint8_t*)LeftBytes)[i];
|
||||
|
||||
Extra[LeftBytesLength] = 0x80;
|
||||
*(uint64_t*)(Extra + (LeftBytesLength >= 64 - 8 ? 128 - 8 : 64 - 8)) = _bswap64(TotalBytesLength * 8);
|
||||
|
||||
accelc_SHA1_update(Extra, LeftBytesLength >= 56 ? 128 : 64, Hash);
|
||||
|
||||
Hash->dword[0] = _bswap(Hash->dword[0]);
|
||||
Hash->dword[1] = _bswap(Hash->dword[1]);
|
||||
Hash->dword[2] = _bswap(Hash->dword[2]);
|
||||
Hash->dword[3] = _bswap(Hash->dword[3]);
|
||||
Hash->dword[4] = _bswap(Hash->dword[4]);
|
||||
}
|
||||
|
||||
void accelc_SHA1(const void* __restrict srcBytes, size_t srclen,
|
||||
SHA1_DIGEST* __restrict Hash) {
|
||||
accelc_SHA1_init(Hash);
|
||||
accelc_SHA1_update(srcBytes, srclen, Hash);
|
||||
accelc_SHA1_final((uint8_t*)srcBytes + (srclen / SHA1_BLOCKSIZE) * SHA1_BLOCKSIZE, srclen % SHA1_BLOCKSIZE, srclen, Hash, Hash);
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct _SHA1_DIGEST {
|
||||
union {
|
||||
uint8_t byte[20];
|
||||
uint32_t dword[5];
|
||||
};
|
||||
} SHA1_DIGEST, SHA1_BUFFER;
|
||||
|
||||
void accelc_SHA1_init(SHA1_BUFFER* HashBuffer);
|
||||
|
||||
void accelc_SHA1_update(const void* __restrict srcBytes, size_t srcBytesLength,
|
||||
SHA1_BUFFER* __restrict HashBuffer);
|
||||
|
||||
void accelc_SHA1_final(const void* __restrict LeftBytes, size_t LeftBytesLength, uint64_t TotalBytesLength,
|
||||
const SHA1_BUFFER* HashBuffer, SHA1_DIGEST* Hash);
|
||||
|
||||
void accelc_SHA1(const void* __restrict srcBytes, size_t srclen,
|
||||
SHA1_DIGEST* __restrict Hash);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,208 @@
|
||||
#pragma once
|
||||
#include "FileMapper.hpp"
|
||||
#include "RSACipher.hpp"
|
||||
|
||||
#include <capstone/capstone.h>
|
||||
#include "ExceptionCapstone.hpp"
|
||||
#include "ResourceGuardCapstone.hpp"
|
||||
|
||||
#include "ImageInterpreter.hpp"
|
||||
|
||||
// lib required by capstone
|
||||
#pragma comment(lib, "legacy_stdio_definitions.lib")
|
||||
#if defined(_M_AMD64)
|
||||
#pragma comment(lib, "capstone_static.lib")
|
||||
#else
|
||||
#pragma comment(lib, "capstone.lib")
|
||||
#endif
|
||||
|
||||
#undef __BASE_FILE__
|
||||
#define __BASE_FILE__ "PatchSolution.hpp"
|
||||
|
||||
class PatchSolution{
|
||||
public:
|
||||
virtual void SetFile(FileMapper* pLibccFile) = 0;
|
||||
virtual bool FindPatchOffset() noexcept = 0;
|
||||
virtual bool CheckKey(RSACipher* pCipher) const = 0;
|
||||
virtual void MakePatch(RSACipher* pCipher) const = 0;
|
||||
virtual ~PatchSolution() {}
|
||||
};
|
||||
|
||||
// PatchSolution0 will replace the RSA public key stored in main application.
|
||||
class PatchSolution0 : public PatchSolution {
|
||||
private:
|
||||
static const char Keyword[461];
|
||||
static constexpr size_t KeywordLength = 460;
|
||||
|
||||
ImageInterpreter _TargetFile;
|
||||
off_t PatchOffset;
|
||||
public:
|
||||
|
||||
PatchSolution0() :
|
||||
PatchOffset(-1) {}
|
||||
|
||||
virtual void SetFile(FileMapper* pMainApp) override {
|
||||
if (!_TargetFile.ParseImage(pMainApp->GetView<PVOID>(), true)) {
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"Invalid PE file.");
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool CheckKey(RSACipher* pCipher) const override;
|
||||
|
||||
// Return true if found, other return false
|
||||
virtual bool FindPatchOffset() noexcept override;
|
||||
|
||||
// Make a patch based on an RSA private key given
|
||||
// Return true if success, otherwise return false
|
||||
virtual void MakePatch(RSACipher* cipher) const override;
|
||||
};
|
||||
|
||||
// PatchSolution1, 2, 3 will replace the RSA public key stored in libcc.dll
|
||||
|
||||
class PatchSolution1 : public PatchSolution {
|
||||
private:
|
||||
|
||||
enum KeywordDataType {
|
||||
IMM_DATA,
|
||||
STRING_DATA
|
||||
};
|
||||
|
||||
struct KeywordInfo {
|
||||
const char* PtrToData;
|
||||
size_t Length;
|
||||
KeywordDataType Type;
|
||||
};
|
||||
|
||||
struct PatchPointInfo {
|
||||
uint8_t* PtrToPatch;
|
||||
size_t PatchSize;
|
||||
size_t MaxPatchSize;
|
||||
};
|
||||
|
||||
static constexpr size_t KeywordsCount = 5;
|
||||
static const KeywordInfo Keywords[KeywordsCount];
|
||||
|
||||
ImageInterpreter _TargetFile;
|
||||
mutable PatchPointInfo _Patches[KeywordsCount];
|
||||
public:
|
||||
PatchSolution1() : _Patches{ } {}
|
||||
|
||||
virtual void SetFile(FileMapper* pLibccFile) override {
|
||||
if (!_TargetFile.ParseImage(pLibccFile->GetView<PVOID>(), true)) {
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"Invalid PE file.");
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool CheckKey(RSACipher* pCipher) const override;
|
||||
|
||||
virtual bool FindPatchOffset() noexcept override;
|
||||
|
||||
virtual void MakePatch(RSACipher* pCipher) const override;
|
||||
};
|
||||
|
||||
class PatchSolution2 : public PatchSolution {
|
||||
private:
|
||||
static constexpr size_t KeywordsCount = 0x188;
|
||||
static const char KeywordsMeta[KeywordsCount + 1];
|
||||
static uint8_t Keywords[KeywordsCount][5];
|
||||
|
||||
ImageInterpreter _TargetFile;
|
||||
off_t PatchOffsets[KeywordsCount];
|
||||
|
||||
void BuildKeywords() noexcept;
|
||||
public:
|
||||
PatchSolution2() {
|
||||
memset(PatchOffsets, -1, sizeof(PatchOffsets));
|
||||
}
|
||||
|
||||
virtual void SetFile(FileMapper* pLibccFile) override {
|
||||
if (!_TargetFile.ParseImage(pLibccFile->GetView<PVOID>(), true)) {
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"Invalid PE file.");
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool CheckKey(RSACipher* pCipher) const override;
|
||||
|
||||
virtual bool FindPatchOffset() noexcept override;
|
||||
|
||||
virtual void MakePatch(RSACipher* pCipher) const override;
|
||||
};
|
||||
|
||||
class PatchSolution3 : public PatchSolution {
|
||||
private:
|
||||
enum KeywordDataType {
|
||||
IMM_DATA,
|
||||
STRING_DATA,
|
||||
};
|
||||
|
||||
struct KeywordType {
|
||||
uint8_t Data[8];
|
||||
size_t Length;
|
||||
KeywordDataType Type;
|
||||
bool NotRecommendedToModify;
|
||||
};
|
||||
|
||||
struct BranchContext {
|
||||
const uint8_t* PtrOfCode;
|
||||
size_t SizeOfCode;
|
||||
#if defined(_M_AMD64)
|
||||
uint64_t Rip;
|
||||
#elif defined(_M_IX86)
|
||||
uint64_t Eip;
|
||||
#else
|
||||
#error "Unknown architecture."
|
||||
#endif
|
||||
};
|
||||
|
||||
struct PatchPointInfo {
|
||||
uint8_t* PtrToRelativeCode;
|
||||
uint64_t RelativeCodeRVA;
|
||||
uint8_t* PtrToPatch;
|
||||
size_t PatchSize;
|
||||
char* PtrToOriginalString;
|
||||
char* PtrToReplaceString;
|
||||
};
|
||||
|
||||
static constexpr size_t KeywordsCount = 111;
|
||||
static const KeywordType Keywords[KeywordsCount];
|
||||
|
||||
ResourceGuard<CapstoneHandleTraits> _CapstoneHandle;
|
||||
ImageInterpreter _TargetFile;
|
||||
mutable PatchPointInfo _Patches[KeywordsCount];
|
||||
|
||||
bool CheckIfMatchPattern(cs_insn* PtrToInstruction) const;
|
||||
|
||||
bool CheckIfFound(cs_insn* PtrToInstruction,
|
||||
size_t i) const;
|
||||
|
||||
PatchPointInfo CreatePatchPoint(const uint8_t* PtrToCode,
|
||||
cs_insn* PtrToInstruction,
|
||||
size_t i) const;
|
||||
|
||||
BranchContext GetJumpedBranch(const BranchContext& NotJumpedBranch,
|
||||
cs_insn* PtrToJmpInstruction) const;
|
||||
|
||||
BranchContext HandleJcc(const BranchContext& NotJumpedBranch,
|
||||
const BranchContext& JumpedBranch,
|
||||
size_t i) const;
|
||||
public:
|
||||
|
||||
PatchSolution3();
|
||||
|
||||
virtual void SetFile(FileMapper* pLibccFile) override {
|
||||
if (!_TargetFile.ParseImage(pLibccFile->GetView<PVOID>())) {
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"Invalid PE file.");
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool FindPatchOffset() noexcept override;
|
||||
virtual bool CheckKey(RSACipher* pCipher) const override;
|
||||
virtual void MakePatch(RSACipher* pCipher) const override;
|
||||
virtual ~PatchSolution3() = default;
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
#include "PatchSolution.hpp"
|
||||
#include <tchar.h>
|
||||
#include "Helper.hpp"
|
||||
|
||||
#undef __BASE_FILE__
|
||||
#define __BASE_FILE__ "PatchSolution0.cpp"
|
||||
|
||||
const char PatchSolution0::Keyword[461] =
|
||||
"-----BEGIN PUBLIC KEY-----\r\n"
|
||||
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw1dqF3SkCaAAmMzs889I\r\n"
|
||||
"qdW9M2dIdh3jG9yPcmLnmJiGpBF4E9VHSMGe8oPAy2kJDmdNt4BcEygvssEfginv\r\n"
|
||||
"a5t5jm352UAoDosUJkTXGQhpAWMF4fBmBpO3EedG62rOsqMBgmSdAyxCSPBRJIOF\r\n"
|
||||
"R0QgZFbRnU0frj34fiVmgYiLuZSAmIbs8ZxiHPdp1oD4tUpvsFci4QJtYNjNnGU2\r\n"
|
||||
"WPH6rvChGl1IRKrxMtqLielsvajUjyrgOC6NmymYMvZNER3htFEtL1eQbCyTfDmt\r\n"
|
||||
"YyQ1Wt4Ot12lxf0wVIR5mcGN7XCXJRHOFHSf1gzXWabRSvmt1nrl7sW6cjxljuuQ\r\n"
|
||||
"awIDAQAB\r\n"
|
||||
"-----END PUBLIC KEY-----\r\n";
|
||||
|
||||
bool PatchSolution0::FindPatchOffset() noexcept {
|
||||
PatchOffset = -1;
|
||||
|
||||
auto PtrToResourceSectionHeader =
|
||||
_TargetFile.GetSectionHeader(".rsrc");
|
||||
auto PtrToResourceSection =
|
||||
_TargetFile.GetSectionView<uint8_t>(".rsrc");
|
||||
|
||||
if (PtrToResourceSectionHeader == nullptr ||
|
||||
PtrToResourceSection == nullptr)
|
||||
return false;
|
||||
|
||||
for (DWORD i = 0; i < PtrToResourceSectionHeader->SizeOfRawData; ++i) {
|
||||
if (memcmp(PtrToResourceSection + i, Keyword, KeywordLength) == 0) {
|
||||
PatchOffset = PtrToResourceSectionHeader->PointerToRawData + i;
|
||||
_tprintf_s(TEXT("MESSAGE: PatchSolution0: Keyword has been found: offset = +0x%08lx.\n"), PatchOffset);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PatchSolution0::CheckKey(RSACipher* pCipher) const {
|
||||
std::string PublicKeyPem =
|
||||
pCipher->ExportKeyString<RSACipher::KeyType::PublicKey, RSACipher::KeyFormat::PEM>();
|
||||
Helper::ReplaceSubString(PublicKeyPem, "\n", "\r\n");
|
||||
return PublicKeyPem.length() == KeywordLength;
|
||||
}
|
||||
|
||||
void PatchSolution0::MakePatch(RSACipher* cipher) const {
|
||||
uint8_t* pFileView = _TargetFile.GetImageBaseView<uint8_t>();
|
||||
std::string PublicKeyPEM;
|
||||
|
||||
PublicKeyPEM =
|
||||
cipher->ExportKeyString<RSACipher::KeyType::PublicKey, RSACipher::KeyFormat::PEM>();
|
||||
Helper::ReplaceSubString(PublicKeyPEM, "\n", "\r\n");
|
||||
|
||||
_putts(TEXT("******************************************"));
|
||||
_putts(TEXT("* PatchSulution0 *"));
|
||||
_putts(TEXT("******************************************"));
|
||||
_tprintf_s(TEXT("@ +0x%08x\nPrevious:\n"), PatchOffset);
|
||||
Helper::PrintMemory(pFileView + PatchOffset,
|
||||
pFileView + PatchOffset + KeywordLength,
|
||||
pFileView);
|
||||
|
||||
memcpy(pFileView + PatchOffset, PublicKeyPEM.c_str(), KeywordLength);
|
||||
|
||||
_putts(TEXT("After:"));
|
||||
Helper::PrintMemory(pFileView + PatchOffset,
|
||||
pFileView + PatchOffset + KeywordLength,
|
||||
pFileView);
|
||||
}
|
||||
@@ -0,0 +1,320 @@
|
||||
#include "PatchSolution.hpp"
|
||||
#include <tchar.h>
|
||||
#include "Helper.hpp"
|
||||
|
||||
#undef __BASE_FILE__
|
||||
#define __BASE_FILE__ "PatchSolution1.cpp"
|
||||
|
||||
const PatchSolution1::KeywordInfo PatchSolution1::Keywords[5] = {
|
||||
{
|
||||
"D75125B70767B94145B47C1CB3C0755E"
|
||||
"7CCB8825C5DCE0C58ACF944E08280140"
|
||||
"9A02472FAFFD1CD77864BB821AE36766"
|
||||
"FEEDE6A24F12662954168BFA314BD950"
|
||||
"32B9D82445355ED7BC0B880887D650F5",
|
||||
160,
|
||||
STRING_DATA
|
||||
},
|
||||
|
||||
{
|
||||
"\xfe\xea\xbc\x01",
|
||||
4,
|
||||
IMM_DATA
|
||||
},
|
||||
|
||||
{
|
||||
"E1CED09B9C2186BF71A70C0FE2F1E0AE"
|
||||
"F3BD6B75277AAB20DFAF3D110F75912B"
|
||||
"FB63AC50EC4C48689D1502715243A79F"
|
||||
"39FF2DE2BF15CE438FF885745ED54573"
|
||||
"850E8A9F40EE2FF505EB7476F95ADB78"
|
||||
"3B28CA374FAC4632892AB82FB3BF4715"
|
||||
"FCFE6E82D03731FC3762B6AAC3DF1C3B"
|
||||
"C646FE9CD3C62663A97EE72DB932A301"
|
||||
"312B4A7633100C8CC357262C39A2B3A6"
|
||||
"4B224F5276D5EDBDF0804DC3AC4B8351"
|
||||
"62BB1969EAEBADC43D2511D6E0239287"
|
||||
"81B167A48273B953378D3D2080CC0677"
|
||||
"7E8A2364F0234B81064C5C739A8DA28D"
|
||||
"C5889072BF37685CBC94C2D31D0179AD"
|
||||
"86D8E3AA8090D4F0B281BE37E0143746"
|
||||
"E6049CCC06899401264FA471C016A96C"
|
||||
"79815B55BBC26B43052609D9D175FBCD"
|
||||
"E455392F10E51EC162F51CF732E6BB39"
|
||||
"1F56BBFD8D957DF3D4C55B71CEFD54B1"
|
||||
"9C16D458757373E698D7E693A8FC3981"
|
||||
"5A8BF03BA05EA8C8778D38F9873D62B4"
|
||||
"460F41ACF997C30E7C3AF025FA171B5F"
|
||||
"5AD4D6B15E95C27F6B35AD61875E5505"
|
||||
"449B4E",
|
||||
742,
|
||||
STRING_DATA
|
||||
},
|
||||
|
||||
{
|
||||
"\x59\x08\x01\x00",
|
||||
4,
|
||||
IMM_DATA
|
||||
},
|
||||
|
||||
{
|
||||
"92933",
|
||||
5,
|
||||
STRING_DATA
|
||||
}
|
||||
};
|
||||
|
||||
bool PatchSolution1::CheckKey(RSACipher* cipher) const {
|
||||
std::string RSAPublicKeyPEM =
|
||||
cipher->ExportKeyString<RSACipher::KeyType::PublicKey, RSACipher::KeyFormat::PEM>();
|
||||
Helper::ReplaceSubString(RSAPublicKeyPEM, "\n", "\r\n");
|
||||
std::string EncryptedPem =
|
||||
Helper::NavicatCipher.EncryptString(RSAPublicKeyPEM);
|
||||
|
||||
if (EncryptedPem.length() != 920)
|
||||
return false;
|
||||
|
||||
// we require the chars in [p1, p2) of EncryptedPem must be number chars
|
||||
size_t p1, p2;
|
||||
|
||||
p1 = _Patches[0].MaxPatchSize;
|
||||
p2 = Keywords[0].Length + 8; // 8 = strlen("29158142")
|
||||
if (p1 >= p2)
|
||||
p1 = p2 - 1;
|
||||
|
||||
if (('1' <= EncryptedPem[p1] && EncryptedPem[p1] <= '9') == false)
|
||||
return false;
|
||||
|
||||
for (size_t i = p1 + 1; i < p2; ++i)
|
||||
if (('0' <= EncryptedPem[i] && EncryptedPem[i] <= '9') == false)
|
||||
return false;
|
||||
|
||||
_Patches[0].PatchSize = p1;
|
||||
|
||||
p1 = Keywords[0].Length + 8 + _Patches[2].MaxPatchSize;
|
||||
p2 = Keywords[0].Length + 8 + Keywords[2].Length + 5;
|
||||
if (p1 >= p2)
|
||||
p1 = p2 - 1;
|
||||
|
||||
if (('1' <= EncryptedPem[p1] && EncryptedPem[p1] <= '9') == false)
|
||||
return false;
|
||||
|
||||
for (size_t i = p1 + 1; i < p2; ++i)
|
||||
if (('0' <= EncryptedPem[i] && EncryptedPem[i] <= '9') == false)
|
||||
return false;
|
||||
|
||||
_Patches[2].PatchSize = p1 - Keywords[0].Length - 8;
|
||||
|
||||
_Patches[4].PatchSize = Keywords[4].Length;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PatchSolution1::FindPatchOffset() noexcept {
|
||||
PIMAGE_SECTION_HEADER SectionHeader_text = _TargetFile.GetSectionHeader(".text");
|
||||
PIMAGE_SECTION_HEADER SectionHeader_rdata = _TargetFile.GetSectionHeader(".rdata");
|
||||
uint8_t* PtrToSection_text = _TargetFile.GetSectionView<uint8_t>(".text");
|
||||
uint8_t* PtrToSection_rdata = _TargetFile.GetSectionView<uint8_t>(".rdata");
|
||||
PatchPointInfo TempPatches[KeywordsCount] = {};
|
||||
|
||||
if (SectionHeader_text == nullptr)
|
||||
return false;
|
||||
if (SectionHeader_rdata == nullptr)
|
||||
return false;
|
||||
|
||||
// -------------------------
|
||||
// try to search Keywords[0]
|
||||
// -------------------------
|
||||
for (DWORD i = 0; i < SectionHeader_rdata->SizeOfRawData; ++i) {
|
||||
if (memcmp(PtrToSection_rdata + i, Keywords[0].PtrToData, Keywords[0].Length) == 0) {
|
||||
TempPatches[0].PtrToPatch = PtrToSection_rdata + i;
|
||||
|
||||
size_t j = Keywords[0].Length;
|
||||
while (TempPatches[0].PtrToPatch[j] == 0)
|
||||
++j;
|
||||
|
||||
TempPatches[0].MaxPatchSize = j - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (TempPatches[0].PtrToPatch == nullptr)
|
||||
return false;
|
||||
|
||||
// -------------------------
|
||||
// try to search Keywords[2]
|
||||
// -------------------------
|
||||
for (DWORD i = 0; i < SectionHeader_rdata->SizeOfRawData; ++i) {
|
||||
if (memcmp(PtrToSection_rdata + i, Keywords[2].PtrToData, Keywords[2].Length) == 0) {
|
||||
TempPatches[2].PtrToPatch = PtrToSection_rdata + i;
|
||||
|
||||
size_t j = Keywords[2].Length;
|
||||
while (TempPatches[2].PtrToPatch[j] == 0)
|
||||
++j;
|
||||
|
||||
TempPatches[2].MaxPatchSize = j - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (TempPatches[2].PtrToPatch == nullptr)
|
||||
return false;
|
||||
|
||||
// -------------------------
|
||||
// try to search Keywords[4]
|
||||
// -------------------------
|
||||
for (DWORD i = 0; i < SectionHeader_rdata->SizeOfRawData; ++i) {
|
||||
if (memcmp(PtrToSection_rdata + i, Keywords[4].PtrToData, Keywords[4].Length) == 0) {
|
||||
TempPatches[4].PtrToPatch = PtrToSection_rdata + i;
|
||||
|
||||
size_t j = Keywords[4].Length;
|
||||
while (TempPatches[4].PtrToPatch[j] == 0)
|
||||
++j;
|
||||
|
||||
TempPatches[4].MaxPatchSize = j - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (TempPatches[4].PtrToPatch == nullptr)
|
||||
return false;
|
||||
|
||||
// -------------------------
|
||||
// try to search Keywords[1] and Keywords[3]
|
||||
// -------------------------
|
||||
for (DWORD i = 0; i < SectionHeader_text->SizeOfRawData; ++i) {
|
||||
if (memcmp(PtrToSection_text + i, Keywords[1].PtrToData, Keywords[1].Length) == 0) {
|
||||
|
||||
// Keywords[3] must be close to Keywords[1]
|
||||
for (DWORD j = i - 64; j < i + 64; ++j) {
|
||||
if (memcmp(PtrToSection_text + j, Keywords[3].PtrToData, Keywords[3].Length) == 0) {
|
||||
TempPatches[1].PtrToPatch = PtrToSection_text + i;
|
||||
TempPatches[1].PatchSize = Keywords[1].Length;
|
||||
TempPatches[1].MaxPatchSize = Keywords[1].Length;
|
||||
|
||||
TempPatches[3].PtrToPatch = PtrToSection_text + j;
|
||||
TempPatches[3].PatchSize = Keywords[3].Length;
|
||||
TempPatches[3].MaxPatchSize = Keywords[3].Length;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (TempPatches[3].PtrToPatch)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (TempPatches[1].PtrToPatch == nullptr || TempPatches[3].PtrToPatch == nullptr)
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < KeywordsCount; ++i) {
|
||||
_Patches[i] = TempPatches[i];
|
||||
_tprintf_s(TEXT("MESSAGE: PatchSolution1: Keywords[%zu] has been found: offset = +0x%08zx.\n"),
|
||||
i,
|
||||
_Patches[i].PtrToPatch - _TargetFile.GetImageBaseView<uint8_t>());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void PatchSolution1::MakePatch(RSACipher* pCipher) const {
|
||||
uint8_t* pFileView = _TargetFile.GetImageBaseView<uint8_t>();
|
||||
|
||||
std::string PublicKeyPEM =
|
||||
pCipher->ExportKeyString<RSACipher::KeyType::PublicKey, RSACipher::KeyFormat::PEM>();
|
||||
Helper::ReplaceSubString(PublicKeyPEM, "\n", "\r\n");
|
||||
|
||||
std::string EncryptedPEM = Helper::NavicatCipher.EncryptString(PublicKeyPEM);
|
||||
|
||||
// split encrypted_pem_pubkey to 5 part: |160 chars|8 chars|742 chars|5 chars|5 chars|
|
||||
// | |
|
||||
// \ / \ /
|
||||
// ImmValue1 ImmValue3
|
||||
size_t p0, p1, p2, p3, p4, p5;
|
||||
p0 = 0;
|
||||
p1 = p0 + _Patches[0].PatchSize;
|
||||
p2 = Keywords[0].Length + 8;
|
||||
p3 = p2 + _Patches[2].PatchSize;
|
||||
p4 = Keywords[0].Length + 8 + Keywords[2].Length + 5;
|
||||
p5 = 920;
|
||||
|
||||
std::string EncryptedPEM0(EncryptedPEM.begin() + p0, EncryptedPEM.begin() + p1);
|
||||
std::string EncryptedPEM1(EncryptedPEM.begin() + p1, EncryptedPEM.begin() + p2);
|
||||
std::string EncryptedPEM2(EncryptedPEM.begin() + p2, EncryptedPEM.begin() + p3);
|
||||
std::string EncryptedPEM3(EncryptedPEM.begin() + p3, EncryptedPEM.begin() + p4);
|
||||
std::string EncryptedPEM4(EncryptedPEM.begin() + p4, EncryptedPEM.begin() + p5);
|
||||
uint32_t ImmValue1 = std::stoul(EncryptedPEM1.c_str());
|
||||
uint32_t ImmValue3 = std::stoul(EncryptedPEM3.c_str());
|
||||
|
||||
_putts(TEXT("******************************************"));
|
||||
_putts(TEXT("* PatchSulution1 *"));
|
||||
_putts(TEXT("******************************************"));
|
||||
|
||||
// ----------------------------------
|
||||
// process PatchOffsets[0]
|
||||
// ----------------------------------
|
||||
_tprintf_s(TEXT("@ +0x%08zx\nPrevious:\n"), _Patches[0].PtrToPatch - pFileView);
|
||||
Helper::PrintMemory(_Patches[0].PtrToPatch,
|
||||
_Patches[0].PtrToPatch + _Patches[0].PatchSize,
|
||||
pFileView);
|
||||
memcpy(_Patches[0].PtrToPatch, EncryptedPEM0.c_str(), _Patches[0].PatchSize);
|
||||
_putts(TEXT("After:"));
|
||||
Helper::PrintMemory(_Patches[0].PtrToPatch,
|
||||
_Patches[0].PtrToPatch + _Patches[0].PatchSize,
|
||||
pFileView);
|
||||
_putts(TEXT(""));
|
||||
|
||||
// ----------------------------------
|
||||
// process PatchOffsets[1]
|
||||
// ----------------------------------
|
||||
_tprintf_s(TEXT("@ +0x%08zx\nPrevious:\n"), _Patches[1].PtrToPatch - pFileView);
|
||||
Helper::PrintMemory(_Patches[1].PtrToPatch,
|
||||
_Patches[1].PtrToPatch + _Patches[1].PatchSize,
|
||||
pFileView);
|
||||
memcpy(_Patches[1].PtrToPatch, &ImmValue1, sizeof(uint32_t));
|
||||
_putts(TEXT("After:"));
|
||||
Helper::PrintMemory(_Patches[1].PtrToPatch,
|
||||
_Patches[1].PtrToPatch + _Patches[1].PatchSize,
|
||||
pFileView);
|
||||
_putts(TEXT(""));
|
||||
|
||||
// ----------------------------------
|
||||
// process PatchOffsets[2]
|
||||
// ----------------------------------
|
||||
_tprintf_s(TEXT("@ +0x%08zx\nPrevious:\n"), _Patches[2].PtrToPatch - pFileView);
|
||||
Helper::PrintMemory(_Patches[2].PtrToPatch,
|
||||
_Patches[2].PtrToPatch + _Patches[2].PatchSize,
|
||||
pFileView);
|
||||
memcpy(_Patches[2].PtrToPatch, EncryptedPEM2.c_str(), _Patches[2].PatchSize);
|
||||
_putts(TEXT("After:"));
|
||||
Helper::PrintMemory(_Patches[2].PtrToPatch,
|
||||
_Patches[2].PtrToPatch + _Patches[2].PatchSize,
|
||||
pFileView);
|
||||
_putts(TEXT(""));
|
||||
|
||||
// ----------------------------------
|
||||
// process PatchOffsets[3]
|
||||
// ----------------------------------
|
||||
_tprintf_s(TEXT("@ +0x%08zx\nPrevious:\n"), _Patches[3].PtrToPatch - pFileView);
|
||||
Helper::PrintMemory(_Patches[3].PtrToPatch,
|
||||
_Patches[3].PtrToPatch + _Patches[3].PatchSize,
|
||||
pFileView);
|
||||
memcpy(_Patches[3].PtrToPatch, &ImmValue3, sizeof(uint32_t));
|
||||
_putts(TEXT("After:"));
|
||||
Helper::PrintMemory(_Patches[3].PtrToPatch,
|
||||
_Patches[3].PtrToPatch + _Patches[3].PatchSize,
|
||||
pFileView);
|
||||
_putts(TEXT(""));
|
||||
|
||||
// ----------------------------------
|
||||
// process PatchOffsets[4]
|
||||
// ----------------------------------
|
||||
_tprintf_s(TEXT("@ +0x%08zx\nPrevious:\n"), _Patches[4].PtrToPatch - pFileView);
|
||||
Helper::PrintMemory(_Patches[4].PtrToPatch,
|
||||
_Patches[4].PtrToPatch + _Patches[4].PatchSize,
|
||||
pFileView);
|
||||
memcpy(_Patches[4].PtrToPatch, EncryptedPEM4.c_str(), _Patches[4].PatchSize);
|
||||
_putts(TEXT("After:"));
|
||||
Helper::PrintMemory(_Patches[4].PtrToPatch,
|
||||
_Patches[4].PtrToPatch + _Patches[4].PatchSize,
|
||||
pFileView);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,257 @@
|
||||
#include "PatchSolution.hpp"
|
||||
#include <tchar.h>
|
||||
#include "Helper.hpp"
|
||||
|
||||
const char PatchSolution2::KeywordsMeta[KeywordsCount + 1] =
|
||||
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw1dqF3SkCaAAmMzs889I"
|
||||
"qdW9M2dIdh3jG9yPcmLnmJiGpBF4E9VHSMGe8oPAy2kJDmdNt4BcEygvssEfginv"
|
||||
"a5t5jm352UAoDosUJkTXGQhpAWMF4fBmBpO3EedG62rOsqMBgmSdAyxCSPBRJIOF"
|
||||
"R0QgZFbRnU0frj34fiVmgYiLuZSAmIbs8ZxiHPdp1oD4tUpvsFci4QJtYNjNnGU2"
|
||||
"WPH6rvChGl1IRKrxMtqLielsvajUjyrgOC6NmymYMvZNER3htFEtL1eQbCyTfDmt"
|
||||
"YyQ1Wt4Ot12lxf0wVIR5mcGN7XCXJRHOFHSf1gzXWabRSvmt1nrl7sW6cjxljuuQ"
|
||||
"awIDAQAB";
|
||||
|
||||
uint8_t PatchSolution2::Keywords[KeywordsCount][5];
|
||||
|
||||
bool PatchSolution2::CheckKey(RSACipher* pCipher) const {
|
||||
std::string PublicKeyPEM =
|
||||
pCipher->ExportKeyString<RSACipher::KeyType::PublicKey, RSACipher::KeyFormat::PEM>();
|
||||
|
||||
PublicKeyPEM.erase(PublicKeyPEM.find("-----BEGIN PUBLIC KEY-----"), 26);
|
||||
PublicKeyPEM.erase(PublicKeyPEM.find("-----END PUBLIC KEY-----"), 24);
|
||||
{
|
||||
std::string::size_type pos = 0;
|
||||
while ((pos = PublicKeyPEM.find("\n", pos)) != std::string::npos) {
|
||||
PublicKeyPEM.erase(pos, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return PublicKeyPEM.length() == KeywordsCount;
|
||||
}
|
||||
|
||||
#if defined(_M_X64)
|
||||
|
||||
void PatchSolution2::BuildKeywords() noexcept {
|
||||
for (size_t i = 0; i < KeywordsCount; ++i) {
|
||||
Keywords[i][0] = 0x83; // Keywords[i] = asm('xor eax, KeywordsMeta[i]') +
|
||||
Keywords[i][1] = 0xf0;
|
||||
Keywords[i][2] = KeywordsMeta[i];
|
||||
Keywords[i][3] = 0x88; // asm_prefix('mov byte ptr ds:xxxxxxxxxxxxxxxx, al')
|
||||
Keywords[i][4] = 0x05;
|
||||
}
|
||||
}
|
||||
|
||||
bool PatchSolution2::FindPatchOffset() noexcept {
|
||||
PIMAGE_SECTION_HEADER textSectionHeader = _TargetFile.GetSectionHeader(".text");
|
||||
uint8_t* PtrToSectiontext = _TargetFile.GetSectionView<uint8_t>(".text");
|
||||
off_t Offsets[KeywordsCount];
|
||||
memset(Offsets, -1, sizeof(Offsets));
|
||||
|
||||
if (textSectionHeader == nullptr)
|
||||
return false;
|
||||
if (PtrToSectiontext == nullptr)
|
||||
return false;
|
||||
|
||||
BuildKeywords();
|
||||
|
||||
// Find offsets
|
||||
{
|
||||
size_t FirstKeywordCounter = 0;
|
||||
uint32_t Hints[9];
|
||||
DWORD PossibleRangeStart = 0xffffffff;
|
||||
DWORD PossibleRangeEnd;
|
||||
for (DWORD i = 0; i < textSectionHeader->SizeOfRawData; ++i) {
|
||||
if (memcmp(PtrToSectiontext + i, Keywords[0], sizeof(Keywords[0])) == 0) {
|
||||
Hints[FirstKeywordCounter++] =
|
||||
*reinterpret_cast<uint32_t*>(PtrToSectiontext + i + sizeof(Keywords[0])) +
|
||||
i + sizeof(Keywords[0]) + sizeof(uint32_t);
|
||||
if (i < PossibleRangeStart)
|
||||
PossibleRangeStart = i;
|
||||
}
|
||||
}
|
||||
|
||||
PossibleRangeStart -= 0x1000;
|
||||
PossibleRangeEnd = PossibleRangeStart + 0x100000;
|
||||
|
||||
// Keywords[0] should occur 9 times.
|
||||
// Because there's only 9 'M' chars in `KeywordsMeta`.
|
||||
if (FirstKeywordCounter != 9)
|
||||
return false;
|
||||
|
||||
Helper::QuickSort(Hints, 0, _countof(Hints));
|
||||
|
||||
// assert
|
||||
// if not satisfied, refuse to patch
|
||||
if (Hints[8] - Hints[0] != 0x18360F8F8 - 0x18360F7D0)
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < KeywordsCount; ++i) {
|
||||
if (Offsets[i] != -1)
|
||||
continue;
|
||||
|
||||
for (DWORD j = PossibleRangeStart; j < PossibleRangeEnd; ++j) {
|
||||
if (memcmp(PtrToSectiontext + j, Keywords[i], sizeof(Keywords[i])) == 0) {
|
||||
off_t index =
|
||||
*reinterpret_cast<uint32_t*>(PtrToSectiontext + j + sizeof(Keywords[i])) +
|
||||
j + sizeof(Keywords[i]) + sizeof(uint32_t) - Hints[0];
|
||||
|
||||
if (0 <= index && index < KeywordsCount && KeywordsMeta[index] == KeywordsMeta[i]) {
|
||||
Offsets[index] = textSectionHeader->PointerToRawData + j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if not found, refuse to patch
|
||||
if (Offsets[i] == -1)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static_assert(sizeof(PatchOffsets) == sizeof(Offsets));
|
||||
memcpy(PatchOffsets, Offsets, sizeof(PatchOffsets));
|
||||
|
||||
for (size_t i = 0; i < KeywordsCount; ++i)
|
||||
_tprintf_s(TEXT("MESSAGE: PatchSolution2: Keywords[%zu] has been found: offset = +0x%08lx.\n"),
|
||||
i,
|
||||
PatchOffsets[i]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void PatchSolution2::BuildKeywords() noexcept {
|
||||
for (size_t i = 0; i < KeywordsCount; ++i) {
|
||||
switch (i % 3) {
|
||||
case 0:
|
||||
Keywords[i][0] = 0x83; // Keywords[i] = asm('xor edx, KeywordsMeta[i]') +
|
||||
Keywords[i][1] = 0xf2;
|
||||
Keywords[i][2] = KeywordsMeta[i];
|
||||
Keywords[i][3] = 0x88; // asm_prefix('mov byte ptr ds:xxxxxxxx, dl')
|
||||
Keywords[i][4] = 0x15;
|
||||
break;
|
||||
case 1:
|
||||
Keywords[i][0] = 0x83; // Keywords[i] = asm('xor eax, KeywordsMeta[i]') +
|
||||
Keywords[i][1] = 0xf0;
|
||||
Keywords[i][2] = KeywordsMeta[i];
|
||||
Keywords[i][3] = 0xa2; // asm_prefix('mov byte ptr ds:xxxxxxxx, al')
|
||||
break;
|
||||
default:
|
||||
Keywords[i][0] = 0x83; // Keywords[i] = asm('xor ecx, KeywordsMeta[i]') +
|
||||
Keywords[i][1] = 0xf1;
|
||||
Keywords[i][2] = KeywordsMeta[i];
|
||||
Keywords[i][3] = 0x88; // asm_prefix('mov byte ptr ds:xxxxxxxx, cl')
|
||||
Keywords[i][4] = 0x0D;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool PatchSolution2::FindPatchOffset() noexcept {
|
||||
PIMAGE_SECTION_HEADER textSectionHeader = _TargetFile.GetSectionHeader(".text");
|
||||
uint8_t* PtrToSectiontext = _TargetFile.GetSectionView<uint8_t>(".text");
|
||||
off_t Offsets[KeywordsCount];
|
||||
memset(Offsets, -1, sizeof(Offsets));
|
||||
|
||||
if (textSectionHeader == nullptr)
|
||||
return false;
|
||||
if (PtrToSectiontext == nullptr)
|
||||
return false;
|
||||
|
||||
BuildKeywords();
|
||||
|
||||
// Find offsets
|
||||
{
|
||||
size_t FirstKeywordCounter = 0;
|
||||
uint32_t Hints[3];
|
||||
DWORD PossibleRangeStart = 0xffffffff;
|
||||
DWORD PossibleRangeEnd;
|
||||
for (DWORD i = 0; i < textSectionHeader->SizeOfRawData; ++i) {
|
||||
if (memcmp(PtrToSectiontext + i, Keywords[0], sizeof(Keywords[0])) == 0) {
|
||||
Hints[FirstKeywordCounter++] =
|
||||
*reinterpret_cast<uint32_t*>(PtrToSectiontext + i + sizeof(Keywords[0]));
|
||||
if (i < PossibleRangeStart)
|
||||
PossibleRangeStart = i;
|
||||
}
|
||||
}
|
||||
|
||||
PossibleRangeStart -= 0x1000;
|
||||
PossibleRangeEnd = PossibleRangeStart + 0x100000;
|
||||
|
||||
// Keywords[0] should occur 3 times.
|
||||
if (FirstKeywordCounter != 3)
|
||||
return false;
|
||||
|
||||
Helper::QuickSort(Hints, 0, _countof(Hints));
|
||||
|
||||
// assert
|
||||
// if not satisfied, refuse to patch
|
||||
if (Hints[2] - Hints[0] != 0x127382BE - 0x12738210)
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < KeywordsCount; ++i) {
|
||||
uint8_t CurrentKeyword[9];
|
||||
size_t CurrentKeywordSize = i % 3 == 1 ? 4 : 5;
|
||||
memcpy(CurrentKeyword, Keywords[i], CurrentKeywordSize);
|
||||
*reinterpret_cast<uint32_t*>(CurrentKeyword + CurrentKeywordSize) = Hints[0] + i;
|
||||
CurrentKeywordSize += sizeof(uint32_t);
|
||||
|
||||
for (DWORD j = PossibleRangeStart; j < PossibleRangeEnd; ++j) {
|
||||
if (memcmp(PtrToSectiontext + j, CurrentKeyword, CurrentKeywordSize) == 0) {
|
||||
Offsets[i] = textSectionHeader->PointerToRawData + j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if not found, refuse to patch
|
||||
if (Offsets[i] == -1)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static_assert(sizeof(PatchOffsets) == sizeof(Offsets));
|
||||
memcpy(PatchOffsets, Offsets, sizeof(PatchOffsets));
|
||||
|
||||
for (size_t i = 0; i < KeywordsCount; ++i)
|
||||
_tprintf_s(TEXT("MESSAGE: PatchSolution2: Keywords[%zu] has been found: offset = +0x%08lx.\n"),
|
||||
i,
|
||||
PatchOffsets[i]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void PatchSolution2::MakePatch(RSACipher* pCipher) const {
|
||||
uint8_t* pFileView = _TargetFile.GetImageBaseView<uint8_t>();
|
||||
std::string PublicKeyPEM =
|
||||
pCipher->ExportKeyString<RSACipher::KeyType::PublicKey, RSACipher::KeyFormat::PEM>();
|
||||
|
||||
PublicKeyPEM.erase(PublicKeyPEM.find("-----BEGIN PUBLIC KEY-----"), 26);
|
||||
PublicKeyPEM.erase(PublicKeyPEM.find("-----END PUBLIC KEY-----"), 24);
|
||||
{
|
||||
std::string::size_type pos = 0;
|
||||
while ((pos = PublicKeyPEM.find("\n", pos)) != std::string::npos) {
|
||||
PublicKeyPEM.erase(pos, 1);
|
||||
}
|
||||
}
|
||||
|
||||
_putts(TEXT("******************************************"));
|
||||
_putts(TEXT("* PatchSulution2 *"));
|
||||
_putts(TEXT("******************************************"));
|
||||
|
||||
for (size_t i = 0; i < KeywordsCount; ++i) {
|
||||
_tprintf_s(TEXT("@ +0x%08lx: %02X %02X %02X ---> "),
|
||||
PatchOffsets[i],
|
||||
pFileView[PatchOffsets[i]],
|
||||
pFileView[PatchOffsets[i] + 1],
|
||||
pFileView[PatchOffsets[i] + 2]);
|
||||
pFileView[PatchOffsets[i] + 2] = PublicKeyPEM[i];
|
||||
_tprintf_s(TEXT("%02X %02X %02X\n"),
|
||||
pFileView[PatchOffsets[i]],
|
||||
pFileView[PatchOffsets[i] + 1],
|
||||
pFileView[PatchOffsets[i] + 2]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,768 @@
|
||||
#include "PatchSolution.hpp"
|
||||
#include <tchar.h>
|
||||
#include "Helper.hpp"
|
||||
|
||||
#undef __BASE_FILE__
|
||||
#define __BASE_FILE__ "PatchSolution3.cpp"
|
||||
|
||||
// ----------- avoid link error caused by capstone_static.lib
|
||||
#define stdin (__acrt_iob_func(0))
|
||||
#define stdout (__acrt_iob_func(1))
|
||||
#define stderr (__acrt_iob_func(2))
|
||||
|
||||
FILE _iob[] = { *stdin, *stdout, *stderr };
|
||||
extern "C" FILE * __cdecl __iob_func(void) { return _iob; }
|
||||
// ------------
|
||||
|
||||
#if defined(_M_AMD64)
|
||||
#define REG_IP Rip
|
||||
#else
|
||||
#define REG_IP Eip
|
||||
#endif
|
||||
|
||||
const PatchSolution3::KeywordType PatchSolution3::Keywords[KeywordsCount] = {
|
||||
{ { 0x4d, 0x49, 0x49 }, 3, STRING_DATA, false },
|
||||
{ { 0x42, 0x49 }, 2, IMM_DATA, false },
|
||||
{ { 0x6a }, 1, IMM_DATA, false },
|
||||
{ { 0x41 }, 1, IMM_DATA, false },
|
||||
{ { 0x4e, 0x42, 0x67, 0x6b }, 4, IMM_DATA, false },
|
||||
{ { 0x71 }, 1, IMM_DATA, false },
|
||||
{ { 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77 }, 6, STRING_DATA, false },
|
||||
{ { 0x30 }, 1, STRING_DATA, true },
|
||||
{ { 0x42 }, 1, IMM_DATA, false },
|
||||
{ { 0x41 }, 1, IMM_DATA, false },
|
||||
{ { 0x51, 0x45, 0x46, 0x41, 0x41, 0x4f, 0x43 }, 7, STRING_DATA, false },
|
||||
{ { 0x41, 0x51, 0x38, 0x41, 0x4d, 0x49 }, 6, STRING_DATA, false },
|
||||
{ { 0x49, 0x42 }, 2, STRING_DATA, false },
|
||||
{ { 0x43, 0x67, 0x4b, 0x43 }, 4, IMM_DATA, false },
|
||||
{ { 0x41, 0x51 }, 2, STRING_DATA, false },
|
||||
{ { 0x45, 0x41, 0x77, 0x31 }, 4, IMM_DATA, false },
|
||||
{ { 0x64, 0x71, 0x46, 0x33 }, 4, IMM_DATA, false },
|
||||
{ { 0x53 }, 1, STRING_DATA, true },
|
||||
{ { 0x6b, 0x43, 0x61, 0x41, 0x41, 0x6d }, 6, STRING_DATA, false },
|
||||
{ { 0x4d, 0x7a, 0x73, 0x38 }, 4, IMM_DATA, false },
|
||||
{ { 0x38, 0x39, 0x49, 0x71 }, 4, IMM_DATA, false },
|
||||
{ { 0x64 }, 1, IMM_DATA, false },
|
||||
{ { 0x57 }, 1, IMM_DATA, false },
|
||||
{ { 0x39, 0x4d, 0x32, 0x64 }, 4, IMM_DATA, false },
|
||||
{ { 0x49, 0x64, 0x68 }, 3, STRING_DATA, false },
|
||||
{ { 0x33, 0x6a }, 2, IMM_DATA, false },
|
||||
{ { 0x47, 0x39, 0x79, 0x50 }, 4, IMM_DATA, false },
|
||||
{ { 0x63, 0x6d }, 2, IMM_DATA, false },
|
||||
{ { 0x4c }, 1, IMM_DATA, false },
|
||||
{ { 0x6e, 0x6d, 0x4a }, 3, STRING_DATA, false },
|
||||
{ { 0x69, 0x47, 0x70, 0x42, 0x46, 0x34, 0x45 }, 7, STRING_DATA, false },
|
||||
{ { 0x39, 0x56, 0x48, 0x53, 0x4d, 0x47 }, 6, STRING_DATA, false },
|
||||
{ { 0x65, 0x38, 0x6f, 0x50, 0x41, 0x79, 0x32, 0x6b }, 8, STRING_DATA, false },
|
||||
{ { 0x4a, 0x44 }, 2, STRING_DATA, false },
|
||||
{ { 0x6d, 0x64 }, 2, IMM_DATA, false },
|
||||
{ { 0x4e, 0x74, 0x34 }, 3, STRING_DATA, false },
|
||||
{ { 0x42, 0x63, 0x45, 0x79, 0x67, 0x76 }, 6, STRING_DATA, false },
|
||||
{ { 0x73, 0x73, 0x45, 0x66, 0x67, 0x69 }, 6, STRING_DATA, false },
|
||||
{ { 0x6e, 0x76, 0x61, 0x35, 0x74 }, 5, STRING_DATA, false },
|
||||
{ { 0x35, 0x6a, 0x6d, 0x33, 0x35, 0x32 }, 6, STRING_DATA, false },
|
||||
{ { 0x55, 0x41 }, 2, IMM_DATA, false },
|
||||
{ { 0x6f, 0x44, 0x6f, 0x73 }, 4, IMM_DATA, false },
|
||||
{ { 0x55, 0x4a }, 2, IMM_DATA, false },
|
||||
{ { 0x6b, 0x54, 0x58, 0x47, 0x51 }, 5, STRING_DATA, false },
|
||||
{ { 0x68, 0x70, 0x41, 0x57, 0x4d, 0x46 }, 6, STRING_DATA, false },
|
||||
{ { 0x34, 0x66, 0x42, 0x6d, 0x42 }, 5, STRING_DATA, false },
|
||||
{ { 0x70, 0x4f, 0x33, 0x45 }, 4, IMM_DATA, false },
|
||||
{ { 0x65, 0x64 }, 2, IMM_DATA, false },
|
||||
{ { 0x47 }, 1, IMM_DATA, false },
|
||||
{ { 0x36, 0x32, 0x72, 0x4f, 0x73, 0x71 }, 6, STRING_DATA, false },
|
||||
{ { 0x4d }, 1, IMM_DATA, false },
|
||||
{ { 0x42, 0x67, 0x6d, 0x53 }, 4, STRING_DATA, false },
|
||||
{ { 0x64 }, 1, IMM_DATA, false },
|
||||
{ { 0x41, 0x79, 0x78, 0x43, 0x53 }, 5, STRING_DATA, false },
|
||||
{ { 0x50 }, 1, IMM_DATA, false },
|
||||
{ { 0x42, 0x52, 0x4a, 0x49, 0x4f }, 5, STRING_DATA, false },
|
||||
{ { 0x46, 0x52, 0x30, 0x51, 0x67, 0x5a, 0x46, 0x62 }, 8, STRING_DATA, false },
|
||||
{ { 0x52 }, 1, IMM_DATA, false },
|
||||
{ { 0x6e, 0x55, 0x30, 0x66 }, 4, STRING_DATA, false },
|
||||
{ { 0x72, 0x6a, 0x33, 0x34 }, 4, IMM_DATA, false },
|
||||
{ { 0x66 }, 1, STRING_DATA, true },
|
||||
{ { 0x69, 0x56, 0x6d, 0x67 }, 4, IMM_DATA, false },
|
||||
{ { 0x59, 0x69, 0x4c, 0x75 }, 4, STRING_DATA, false },
|
||||
{ { 0x5a, 0x53, 0x41, 0x6d }, 4, IMM_DATA, false },
|
||||
{ { 0x49, 0x62 }, 2, IMM_DATA, false },
|
||||
{ { 0x73 }, 1, IMM_DATA, false },
|
||||
{ { 0x38, 0x5a, 0x78, 0x69 }, 4, IMM_DATA, false },
|
||||
{ { 0x48 }, 1, IMM_DATA, false },
|
||||
{ { 0x50, 0x64, 0x70, 0x31 }, 4, IMM_DATA, false },
|
||||
{ { 0x6f, 0x44 }, 2, IMM_DATA, false },
|
||||
{ { 0x34 }, 1, IMM_DATA, false },
|
||||
{ { 0x74, 0x55, 0x70, 0x76, 0x73, 0x46 }, 6, STRING_DATA, false },
|
||||
{ { 0x63, 0x69, 0x34, 0x51, 0x4a, 0x74 }, 6, STRING_DATA, false },
|
||||
{ { 0x59, 0x4e, 0x6a, 0x4e, 0x6e, 0x47, 0x55 }, 7, STRING_DATA, false },
|
||||
{ { 0x32, 0x57, 0x50, 0x48 }, 4, STRING_DATA, false },
|
||||
{ { 0x36, 0x72, 0x76, 0x43, 0x68, 0x47, 0x6c }, 7, STRING_DATA, false },
|
||||
{ { 0x31, 0x49, 0x52, 0x4b, 0x72, 0x78, 0x4d, 0x74 }, 8, STRING_DATA, false },
|
||||
{ { 0x71, 0x4c, 0x69, 0x65, 0x6c }, 5, STRING_DATA, false },
|
||||
{ { 0x73, 0x76, 0x61, 0x6a, 0x55, 0x6a, 0x79, 0x72 }, 8, STRING_DATA, false },
|
||||
{ { 0x67 }, 1, STRING_DATA, true },
|
||||
{ { 0x4f, 0x43, 0x36, 0x4e, 0x6d, 0x79, 0x6d, 0x59 }, 8, STRING_DATA, false },
|
||||
{ { 0x4d }, 1, IMM_DATA, false },
|
||||
{ { 0x76, 0x5a, 0x4e }, 3, STRING_DATA, false },
|
||||
{ { 0x45, 0x52, 0x33, 0x68, 0x74 }, 5, STRING_DATA, false },
|
||||
{ { 0x46 }, 1, IMM_DATA, false },
|
||||
{ { 0x45, 0x74, 0x4c, 0x31 }, 4, STRING_DATA, false },
|
||||
{ { 0x65, 0x51, 0x62, 0x43, 0x79 }, 5, STRING_DATA, false },
|
||||
{ { 0x54, 0x66, 0x44, 0x6d, 0x74, 0x59, 0x79, 0x51 }, 8, STRING_DATA, false },
|
||||
{ { 0x31, 0x57, 0x74, 0x34 }, 4, STRING_DATA, false },
|
||||
{ { 0x4f }, 1, IMM_DATA, false },
|
||||
{ { 0x74, 0x31, 0x32, 0x6c, 0x78, 0x66 }, 6, STRING_DATA, false },
|
||||
{ { 0x30 }, 1, IMM_DATA, false },
|
||||
{ { 0x77, 0x56, 0x49, 0x52, 0x35 }, 5, STRING_DATA, false },
|
||||
{ { 0x6d }, 1, IMM_DATA, false },
|
||||
{ { 0x63, 0x47, 0x4e, 0x37 }, 4, STRING_DATA, false },
|
||||
{ { 0x58, 0x43, 0x58, 0x4a }, 4, STRING_DATA, false },
|
||||
{ { 0x52, 0x48, 0x4f, 0x46 }, 4, IMM_DATA, false },
|
||||
{ { 0x48, 0x53 }, 2, IMM_DATA, false },
|
||||
{ { 0x66 }, 1, IMM_DATA, false },
|
||||
{ { 0x31, 0x67, 0x7a, 0x58, 0x57 }, 5, STRING_DATA, false },
|
||||
{ { 0x61 }, 1, IMM_DATA, false },
|
||||
{ { 0x62 }, 1, IMM_DATA, false },
|
||||
{ { 0x52, 0x53 }, 2, STRING_DATA, false },
|
||||
{ { 0x76, 0x6d, 0x74, 0x31, 0x6e }, 5, STRING_DATA, false },
|
||||
{ { 0x72, 0x6c }, 2, STRING_DATA, true },
|
||||
{ { 0x37, 0x73, 0x57 }, 3, STRING_DATA, false },
|
||||
{ { 0x36, 0x63, 0x6a }, 3, STRING_DATA, false },
|
||||
{ { 0x78, 0x6c, 0x6a, 0x75, 0x75, 0x51, 0x61 }, 7, STRING_DATA, false },
|
||||
{ { 0x77, 0x49, 0x44, 0x41 }, 4, STRING_DATA, false },
|
||||
{ { 0x51, 0x41 }, 2, IMM_DATA, false },
|
||||
{ { 0x42 }, 1, IMM_DATA, false },
|
||||
};
|
||||
|
||||
PatchSolution3::PatchSolution3() {
|
||||
cs_err cs_status;
|
||||
csh cs_handle;
|
||||
#if defined(_M_IX86)
|
||||
cs_status = cs_open(CS_ARCH_X86, CS_MODE_32, &cs_handle);
|
||||
#else
|
||||
cs_status = cs_open(CS_ARCH_X86, CS_MODE_64, &cs_handle);
|
||||
#endif
|
||||
if (cs_status != CS_ERR_OK)
|
||||
throw CapstoneError(__BASE_FILE__, __LINE__, cs_status,
|
||||
"cs_open fails.");
|
||||
|
||||
cs_status = cs_option(cs_handle, CS_OPT_DETAIL, CS_OPT_ON);
|
||||
if (cs_status != CS_ERR_OK)
|
||||
throw CapstoneError(__BASE_FILE__, __LINE__, cs_status,
|
||||
"cs_option fails.");
|
||||
|
||||
_CapstoneHandle.TakeHoldOf(cs_handle);
|
||||
memset(_Patches, 0, sizeof(_Patches));
|
||||
}
|
||||
|
||||
#if defined(_M_AMD64)
|
||||
bool PatchSolution3::CheckIfMatchPattern(cs_insn* PtrToInstruction) const {
|
||||
// the instruction we're interested in has one of the following patterns:
|
||||
// 1. mov PTR [MEM], IMM (IMM must consist of printable chars) // for IMM_DATA
|
||||
// 2. lea REG, PTR [MEM] (MEM must point to a non-empty printable string) // for STRING_DATA
|
||||
|
||||
if (_stricmp(PtrToInstruction->mnemonic, "mov") == 0) {
|
||||
if (PtrToInstruction->detail->x86.operands[1].type != X86_OP_IMM)
|
||||
return false;
|
||||
|
||||
uint8_t* PtrToImm =
|
||||
PtrToInstruction->bytes +
|
||||
PtrToInstruction->detail->x86.encoding.imm_offset;
|
||||
uint8_t ImmSize =
|
||||
PtrToInstruction->detail->x86.encoding.imm_size;
|
||||
|
||||
return Helper::IsPrintable(PtrToImm, ImmSize);
|
||||
} else if (_stricmp(PtrToInstruction->mnemonic, "lea") == 0) {
|
||||
// as far as I know, all strings are loaded by "lea REG, QWORD PTR[RIP + disp]"
|
||||
// so it must be "[RIP + disp]"
|
||||
if (PtrToInstruction->detail->x86.operands[1].mem.base != X86_REG_RIP)
|
||||
return false;
|
||||
|
||||
// scale must 1, otherwise pattern mismatches
|
||||
if (PtrToInstruction->detail->x86.operands[1].mem.scale != 1)
|
||||
return false;
|
||||
|
||||
auto StringRva = static_cast<uintptr_t>(
|
||||
PtrToInstruction->address + PtrToInstruction->size + // RIP
|
||||
PtrToInstruction->detail->x86.operands[1].mem.disp
|
||||
);
|
||||
|
||||
auto PtrToString = _TargetFile.RvaToPointer<uint8_t>(StringRva);
|
||||
|
||||
// If not found, pattern mismatches
|
||||
if (PtrToString == nullptr)
|
||||
return false;
|
||||
|
||||
// PtrToString must have at least one char
|
||||
// every char in PtrToString must be printable, otherwise pattern mismatches
|
||||
auto StringLength = strlen(reinterpret_cast<char*>(PtrToString));
|
||||
if (StringLength && Helper::IsPrintable(PtrToString, StringLength))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#else // for i386
|
||||
bool PatchSolution3::CheckIfMatchPattern(cs_insn* PtrToInstruction) const {
|
||||
// the instruction we're interested in has one of the following patterns:
|
||||
// 1. mov PTR [MEM], IMM (IMM must consist of printable chars) // for KeywordType::IMM_DATA
|
||||
// except pattern "mov [ebp - 0x4], IMM"
|
||||
// 2. push IMM (IMM must consist of printable chars) // for KeywordType::IMM_DATA
|
||||
// 3. push offset MEM (MEM must point to a non-empty printable string) // for KeywordType::STRING_DATA
|
||||
//
|
||||
|
||||
if (_stricmp(PtrToInstruction->mnemonic, "mov") == 0) {
|
||||
// filter the case "mov [ebp - 0x4], IMM"
|
||||
// because IMM may consist of printable chars in that case, which can mislead us.
|
||||
//
|
||||
// Here I use "> -0x30" to intensify condition, instead of "== -0x4"
|
||||
if (PtrToInstruction->detail->x86.operands[0].type == X86_OP_MEM &&
|
||||
PtrToInstruction->detail->x86.operands[0].mem.base == X86_REG_EBP &&
|
||||
PtrToInstruction->detail->x86.operands[0].mem.disp > -0x30)
|
||||
return false;
|
||||
|
||||
if (PtrToInstruction->detail->x86.operands[1].type != X86_OP_IMM)
|
||||
return false;
|
||||
|
||||
uint8_t* PtrToImm =
|
||||
PtrToInstruction->bytes +
|
||||
PtrToInstruction->detail->x86.encoding.imm_offset;
|
||||
uint8_t ImmSize =
|
||||
PtrToInstruction->detail->x86.encoding.imm_size;
|
||||
|
||||
// each bytes of ImmValue must be printable;
|
||||
return Helper::IsPrintable(PtrToImm, ImmSize);
|
||||
} else if (_stricmp(PtrToInstruction->mnemonic, "push") == 0) {
|
||||
if (PtrToInstruction->detail->x86.operands[0].type != X86_OP_IMM)
|
||||
return false;
|
||||
|
||||
{ // test if match pattern 2
|
||||
if (Helper::IsPrintable(PtrToInstruction->bytes + PtrToInstruction->detail->x86.encoding.imm_offset,
|
||||
PtrToInstruction->detail->x86.encoding.imm_size))
|
||||
return true;
|
||||
}
|
||||
|
||||
{ // test if match pattern 3
|
||||
auto StringRva = static_cast<uintptr_t>(
|
||||
PtrToInstruction->detail->x86.operands[0].imm -
|
||||
_TargetFile.GetImageNTHeaders()->OptionalHeader.ImageBase
|
||||
);
|
||||
|
||||
auto PtrToString = _TargetFile.RvaToPointer<uint8_t>(StringRva);
|
||||
|
||||
if (PtrToString) {
|
||||
auto StringLength = strlen(reinterpret_cast<char*>(PtrToString));
|
||||
|
||||
if (StringLength && Helper::IsPrintable(PtrToString, StringLength))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_M_AMD64)
|
||||
bool PatchSolution3::CheckIfFound(cs_insn* PtrToInstruction, size_t i) const {
|
||||
auto& op_count = PtrToInstruction->detail->x86.op_count;
|
||||
auto& operands = PtrToInstruction->detail->x86.operands;
|
||||
|
||||
if (PtrToInstruction->detail->x86.op_count != 2)
|
||||
return false;
|
||||
|
||||
if (Keywords[i].Type == IMM_DATA && operands[1].type == X86_OP_IMM) {
|
||||
uint64_t ImmValue = operands[1].imm;
|
||||
uint8_t ImmSize = PtrToInstruction->detail->x86.encoding.imm_size;
|
||||
return
|
||||
memcmp(&ImmValue, Keywords[i].Data, sizeof(uint64_t)) == 0 &&
|
||||
ImmSize == Keywords[i].Length;
|
||||
} else if (Keywords[i].Type == STRING_DATA && operands[1].type == X86_OP_MEM) {
|
||||
auto StringRva = static_cast<uintptr_t>(
|
||||
PtrToInstruction->address + PtrToInstruction->size + // RIP
|
||||
PtrToInstruction->detail->x86.operands[1].mem.disp
|
||||
);
|
||||
|
||||
auto PtrToString = _TargetFile.RvaToPointer<char>(StringRva);
|
||||
|
||||
return
|
||||
PtrToString &&
|
||||
strncmp(PtrToString, reinterpret_cast<const char*>(Keywords[i].Data), Keywords[i].Length) == 0 &&
|
||||
PtrToString[Keywords[i].Length] == '\x00';
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#else
|
||||
bool PatchSolution3::CheckIfFound(cs_insn* PtrToInstruction, size_t i) const {
|
||||
auto& op_count = PtrToInstruction->detail->x86.op_count;
|
||||
auto& operands = PtrToInstruction->detail->x86.operands;
|
||||
|
||||
if (op_count < 1 || operands[op_count - 1].type != X86_OP_IMM)
|
||||
return false;
|
||||
|
||||
if (Keywords[i].Type == IMM_DATA) {
|
||||
uint64_t ImmValue = operands[op_count - 1].imm;
|
||||
uint8_t ImmSize = PtrToInstruction->detail->x86.encoding.imm_size;
|
||||
return
|
||||
memcmp(&ImmValue, Keywords[i].Data, sizeof(uint64_t)) == 0 &&
|
||||
ImmSize == Keywords[i].Length;
|
||||
} else if (Keywords[i].Type == STRING_DATA) {
|
||||
auto StringRva = static_cast<uintptr_t>(
|
||||
operands[op_count - 1].imm -
|
||||
_TargetFile.GetImageNTHeaders()->OptionalHeader.ImageBase
|
||||
);
|
||||
|
||||
auto PtrToString = _TargetFile.RvaToPointer<char>(StringRva);
|
||||
|
||||
return
|
||||
PtrToString &&
|
||||
strncmp(PtrToString, reinterpret_cast<const char*>(Keywords[i].Data), Keywords[i].Length) == 0 &&
|
||||
PtrToString[Keywords[i].Length] == '\x00';
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_M_AMD64)
|
||||
PatchSolution3::PatchPointInfo
|
||||
PatchSolution3::CreatePatchPoint(const uint8_t* PtrToCode,
|
||||
cs_insn* PtrToInstruction,
|
||||
size_t i) const {
|
||||
PatchPointInfo result;
|
||||
|
||||
result.PtrToRelativeCode = const_cast<uint8_t*>(PtrToCode);
|
||||
result.RelativeCodeRVA = PtrToInstruction->address;
|
||||
|
||||
if (PtrToInstruction->detail->x86.operands[1].type == X86_OP_MEM) {
|
||||
auto StringRva = static_cast<uintptr_t>(
|
||||
PtrToInstruction->address + PtrToInstruction->size + // RIP
|
||||
PtrToInstruction->detail->x86.operands[1].mem.disp
|
||||
);
|
||||
|
||||
auto PtrToString = _TargetFile.RvaToPointer<char>(StringRva);
|
||||
|
||||
result.PtrToOriginalString = PtrToString;
|
||||
|
||||
if (Keywords[i].NotRecommendedToModify == false) {
|
||||
result.PtrToPatch = reinterpret_cast<uint8_t*>(result.PtrToOriginalString);
|
||||
result.PatchSize = Keywords[i].Length;
|
||||
} else {
|
||||
result.PtrToPatch =
|
||||
result.PtrToRelativeCode + PtrToInstruction->detail->x86.encoding.disp_offset;
|
||||
result.PatchSize =
|
||||
PtrToInstruction->detail->x86.encoding.disp_size;
|
||||
}
|
||||
} else { // X86_OP_IMM
|
||||
result.PtrToPatch = result.PtrToRelativeCode + PtrToInstruction->detail->x86.encoding.imm_offset;
|
||||
result.PatchSize = PtrToInstruction->detail->x86.encoding.imm_size;
|
||||
result.PtrToOriginalString = nullptr;
|
||||
}
|
||||
|
||||
result.PtrToReplaceString = nullptr;
|
||||
|
||||
return result;
|
||||
}
|
||||
#else // for i386
|
||||
PatchSolution3::PatchPointInfo
|
||||
PatchSolution3::CreatePatchPoint(const uint8_t* PtrToCode,
|
||||
cs_insn* PtrToInstruction,
|
||||
size_t i) const {
|
||||
PatchPointInfo result;
|
||||
|
||||
result.PtrToRelativeCode = const_cast<uint8_t*>(PtrToCode);
|
||||
result.RelativeCodeRVA = PtrToInstruction->address;
|
||||
|
||||
if (Keywords[i].Type == IMM_DATA) {
|
||||
result.PtrToPatch = result.PtrToRelativeCode + PtrToInstruction->detail->x86.encoding.imm_offset;
|
||||
result.PatchSize = PtrToInstruction->detail->x86.encoding.imm_size;
|
||||
result.PtrToOriginalString = nullptr;
|
||||
} else {
|
||||
auto StringRva = static_cast<uintptr_t>(
|
||||
PtrToInstruction->detail->x86.operands[0].imm -
|
||||
_TargetFile.GetImageNTHeaders()->OptionalHeader.ImageBase
|
||||
);
|
||||
|
||||
auto PtrToString = _TargetFile.RvaToPointer<char>(StringRva);
|
||||
|
||||
result.PtrToOriginalString = PtrToString;
|
||||
|
||||
if (Keywords[i].NotRecommendedToModify == false) {
|
||||
result.PtrToPatch = reinterpret_cast<uint8_t*>(result.PtrToOriginalString);
|
||||
result.PatchSize = Keywords[i].Length;
|
||||
} else {
|
||||
result.PtrToPatch =
|
||||
result.PtrToRelativeCode + PtrToInstruction->detail->x86.encoding.imm_offset;
|
||||
result.PatchSize =
|
||||
PtrToInstruction->detail->x86.encoding.imm_size;
|
||||
}
|
||||
}
|
||||
|
||||
result.PtrToReplaceString = nullptr;
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
PatchSolution3::BranchContext
|
||||
PatchSolution3::GetJumpedBranch(const BranchContext& NotJumpedBranch,
|
||||
cs_insn* PtrToJmpInstruction) const {
|
||||
BranchContext JumpedBranch;
|
||||
const BranchContext InvalidBranch = {};
|
||||
|
||||
JumpedBranch.PtrOfCode =
|
||||
_TargetFile.RvaToPointer<uint8_t>(
|
||||
static_cast<uintptr_t>(PtrToJmpInstruction->detail->x86.operands[0].imm)
|
||||
);
|
||||
|
||||
JumpedBranch.SizeOfCode =
|
||||
NotJumpedBranch.SizeOfCode - (JumpedBranch.PtrOfCode - NotJumpedBranch.PtrOfCode);
|
||||
|
||||
JumpedBranch.REG_IP = PtrToJmpInstruction->detail->x86.operands[0].imm;
|
||||
|
||||
if (JumpedBranch.PtrOfCode)
|
||||
return JumpedBranch;
|
||||
else
|
||||
return InvalidBranch;
|
||||
}
|
||||
|
||||
PatchSolution3::BranchContext
|
||||
PatchSolution3::HandleJcc(const BranchContext& A,
|
||||
const BranchContext& B,
|
||||
size_t i) const {
|
||||
const BranchContext InvalidBranch = {};
|
||||
BranchContext BranchA = A;
|
||||
BranchContext BranchB = B;
|
||||
int WeightA = 0;
|
||||
int WeightB = 0;
|
||||
ResourceGuard<CapstoneMallocTraits<cs_insn>> InstructionObjGuard(
|
||||
cs_malloc(_CapstoneHandle)
|
||||
);
|
||||
cs_insn* PtrToInstruction = InstructionObjGuard.GetHandle();
|
||||
|
||||
if (PtrToInstruction == nullptr)
|
||||
return InvalidBranch;
|
||||
|
||||
while (true) {
|
||||
|
||||
int WeightAPrev = WeightA;
|
||||
int WeightBPrev = WeightB;
|
||||
|
||||
// process branch A
|
||||
while (cs_disasm_iter(_CapstoneHandle, &BranchA.PtrOfCode, &BranchA.SizeOfCode, &BranchA.REG_IP, PtrToInstruction)) {
|
||||
// For all x86 mnemonics, only 'jcc' or 'jmp' starts with 'j' or 'J'.
|
||||
// So it should be a new branch if we meet them.
|
||||
if (PtrToInstruction->mnemonic[0] == 'j' || PtrToInstruction->mnemonic[0] == 'J') {
|
||||
BranchContext JumpedBranch = GetJumpedBranch(BranchA, PtrToInstruction);
|
||||
if (JumpedBranch.PtrOfCode == nullptr)
|
||||
return InvalidBranch;
|
||||
|
||||
if (_stricmp(PtrToInstruction->mnemonic, "jmp") == 0) {
|
||||
BranchA = JumpedBranch;
|
||||
} else {
|
||||
BranchA = HandleJcc(BranchA, JumpedBranch, i);
|
||||
if (BranchA.PtrOfCode == nullptr)
|
||||
break;
|
||||
}
|
||||
} else if (_stricmp(PtrToInstruction->mnemonic, "ret") == 0) {
|
||||
return B;
|
||||
} else {
|
||||
if (CheckIfMatchPattern(PtrToInstruction) == false)
|
||||
continue;
|
||||
|
||||
// if match pattern, but keyword doesn't match,
|
||||
// branch A must not be what we want
|
||||
if (CheckIfFound(PtrToInstruction, i) == false)
|
||||
return B;
|
||||
|
||||
// If keyword is succeeded to match
|
||||
// Add WeightA and stop processing branch A
|
||||
WeightA++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// process B branch
|
||||
while (cs_disasm_iter(_CapstoneHandle, &BranchB.PtrOfCode, &BranchB.SizeOfCode, &BranchB.REG_IP, PtrToInstruction)) {
|
||||
// For all x86 mnemonics, only 'jcc' or 'jmp' starts with 'j' or 'J'.
|
||||
// So it should be a new branch if we meet them.
|
||||
if (PtrToInstruction->mnemonic[0] == 'j' || PtrToInstruction->mnemonic[0] == 'J') {
|
||||
BranchContext JumpedBranch = GetJumpedBranch(BranchA, PtrToInstruction);
|
||||
if (JumpedBranch.PtrOfCode == nullptr)
|
||||
return InvalidBranch;
|
||||
|
||||
if (_stricmp(PtrToInstruction->mnemonic, "jmp") == 0) {
|
||||
BranchB = JumpedBranch;
|
||||
} else {
|
||||
BranchB = HandleJcc(BranchB, JumpedBranch, i);
|
||||
if (BranchB.PtrOfCode == nullptr)
|
||||
break;
|
||||
}
|
||||
} else if (_stricmp(PtrToInstruction->mnemonic, "ret") == 0) {
|
||||
return A;
|
||||
} else {
|
||||
if (CheckIfMatchPattern(PtrToInstruction) == false)
|
||||
continue;
|
||||
|
||||
if (CheckIfFound(PtrToInstruction, i) == false)
|
||||
return A;
|
||||
|
||||
WeightB++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (WeightAPrev == WeightA && WeightBPrev == WeightB)
|
||||
return InvalidBranch;
|
||||
|
||||
if (WeightA != WeightB)
|
||||
return WeightA > WeightB ? A : B;
|
||||
else
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
bool PatchSolution3::FindPatchOffset() noexcept {
|
||||
memset(_Patches, 0, sizeof(_Patches));
|
||||
|
||||
uint8_t* pFileView = _TargetFile.GetImageBaseView<uint8_t>();
|
||||
PIMAGE_SECTION_HEADER pSectionHdrOftext = _TargetFile.GetSectionHeader(".text");
|
||||
uint8_t* pSectionOftext = pFileView + pSectionHdrOftext->PointerToRawData;
|
||||
off_t TargetFunctionOffset = -1;
|
||||
|
||||
if (pSectionHdrOftext == nullptr)
|
||||
return false;
|
||||
|
||||
for (DWORD i = 0; i < pSectionHdrOftext->SizeOfRawData; ++i) {
|
||||
const uint32_t Hint = 0x6b67424e;
|
||||
if (*reinterpret_cast<uint32_t*>(pSectionOftext + i) == Hint) {
|
||||
#if defined(_M_AMD64)
|
||||
static const uint8_t BeginBytesOfTargetFunction[] = {
|
||||
0x40, 0x55, // push rbp
|
||||
0x48, 0x8D, 0xAC, 0x24, 0x70, 0xBC, 0xFF, 0xFF, // lea rbp, [rsp-4390h]
|
||||
0xB8, 0x90, 0x44, 0x00, 0x00 // mov eax, 4490h
|
||||
};
|
||||
for (DWORD j = i - 0x250; j < i; ++j) {
|
||||
#else
|
||||
static const uint8_t BeginBytesOfTargetFunction[] = {
|
||||
0x55, // push ebp
|
||||
0x8B, 0xEC, // mov ebp, esp
|
||||
0x6A, 0xFF // push 0xffffffff
|
||||
};
|
||||
for (DWORD j = i - 0x1B0; j < i; ++j) {
|
||||
#endif
|
||||
if (memcmp(pSectionOftext + j,
|
||||
BeginBytesOfTargetFunction,
|
||||
sizeof(BeginBytesOfTargetFunction)) == 0) {
|
||||
TargetFunctionOffset = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (TargetFunctionOffset == -1)
|
||||
return false;
|
||||
|
||||
size_t KeywordIndex = 0;
|
||||
|
||||
{
|
||||
BranchContext CurrentBranchPrevInstruction;
|
||||
BranchContext CurrentBranch;
|
||||
CurrentBranch.PtrOfCode = pSectionOftext + TargetFunctionOffset;
|
||||
#if defined(_M_AMD64)
|
||||
CurrentBranch.SizeOfCode = 0xcd03;
|
||||
#else
|
||||
CurrentBranch.SizeOfCode = 0x9014;
|
||||
#endif
|
||||
CurrentBranch.REG_IP = pSectionHdrOftext->VirtualAddress + TargetFunctionOffset;
|
||||
|
||||
ResourceGuard<CapstoneMallocTraits<cs_insn>> InstructionObj(cs_malloc(_CapstoneHandle));
|
||||
cs_insn* PtrToInstruction = InstructionObj.GetHandle();
|
||||
|
||||
while ((CurrentBranchPrevInstruction = CurrentBranch,
|
||||
cs_disasm_iter(_CapstoneHandle,
|
||||
&CurrentBranch.PtrOfCode,
|
||||
&CurrentBranch.SizeOfCode,
|
||||
&CurrentBranch.REG_IP, PtrToInstruction))) {
|
||||
|
||||
if (PtrToInstruction->mnemonic[0] == 'j' || PtrToInstruction->mnemonic[0] == 'J') {
|
||||
BranchContext JumpedBranch = GetJumpedBranch(CurrentBranch, PtrToInstruction);
|
||||
if (JumpedBranch.PtrOfCode == nullptr)
|
||||
return false;
|
||||
|
||||
if (_stricmp(PtrToInstruction->mnemonic, "jmp") == 0) {
|
||||
CurrentBranch = JumpedBranch;
|
||||
} else {
|
||||
CurrentBranch = HandleJcc(CurrentBranch, JumpedBranch, KeywordIndex);
|
||||
if (CurrentBranch.PtrOfCode == nullptr)
|
||||
return false;
|
||||
}
|
||||
} else if (_stricmp(PtrToInstruction->mnemonic, "ret") == 0) {
|
||||
return false;
|
||||
} else {
|
||||
if (CheckIfMatchPattern(PtrToInstruction) == false)
|
||||
continue;
|
||||
|
||||
if (CheckIfFound(PtrToInstruction, KeywordIndex) == false)
|
||||
return false;
|
||||
|
||||
_Patches[KeywordIndex] =
|
||||
CreatePatchPoint(CurrentBranchPrevInstruction.PtrOfCode,
|
||||
PtrToInstruction,
|
||||
KeywordIndex);
|
||||
|
||||
KeywordIndex++;
|
||||
}
|
||||
|
||||
if (KeywordIndex == KeywordsCount)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (KeywordIndex != KeywordsCount)
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < KeywordsCount; ++i) {
|
||||
_tprintf_s(TEXT("MESSAGE: PatchSolution3: Keywords[%zu] has been found:\n"), i);
|
||||
_tprintf_s(TEXT(" Relative Machine Code Offset = +0x%016zx\n"), _Patches[i].PtrToRelativeCode - pFileView);
|
||||
_tprintf_s(TEXT(" Relative Machine Code RVA = +0x%016llx\n"), _Patches[i].RelativeCodeRVA);
|
||||
_tprintf_s(TEXT(" Patch Offset = +0x%016zx\n"), _Patches[i].PtrToPatch - pFileView);
|
||||
_tprintf_s(TEXT(" Patch Size = %zu byte(s)\n"), _Patches[i].PatchSize);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Brute-force search, str_s should be 1 or 2
|
||||
static off_t SearchString(const void* p, size_t s, const char* str, size_t str_s) {
|
||||
const char* char_ptr = reinterpret_cast<const char*>(p);
|
||||
for (size_t i = 0; i < s; ++i) {
|
||||
if (char_ptr[i] == str[0]) {
|
||||
bool match = true;
|
||||
|
||||
for (size_t j = 1; j < str_s; ++j) {
|
||||
if (char_ptr[i + j] != str[j]) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (match && char_ptr[i + str_s] == '\x00')
|
||||
return static_cast<off_t>(i);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool PatchSolution3::CheckKey(RSACipher* pCipher) const {
|
||||
std::string PublicKeyPem = pCipher->ExportKeyString<RSACipher::KeyType::PublicKey,
|
||||
RSACipher::KeyFormat::PEM>();
|
||||
|
||||
PublicKeyPem.erase(PublicKeyPem.find("-----BEGIN PUBLIC KEY-----"), 26);
|
||||
PublicKeyPem.erase(PublicKeyPem.find("-----END PUBLIC KEY-----"), 24);
|
||||
{
|
||||
std::string::size_type pos = 0;
|
||||
while ((pos = PublicKeyPem.find("\n", pos)) != std::string::npos) {
|
||||
PublicKeyPem.erase(pos, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if(PublicKeyPem.length() != 0x188)
|
||||
return false;
|
||||
|
||||
char* pFileView = _TargetFile.GetImageBaseView<char>();
|
||||
PIMAGE_SECTION_HEADER pSectionHdrOfrdata = _TargetFile.GetSectionHeader(".rdata");
|
||||
char* pSectionOfrdata = pFileView + pSectionHdrOfrdata->PointerToRawData;
|
||||
|
||||
size_t ptr = 0;
|
||||
for (size_t i = 0; i < KeywordsCount; ++i) {
|
||||
if (Keywords[i].NotRecommendedToModify) {
|
||||
off_t offset = 0;
|
||||
|
||||
while (true) {
|
||||
off_t off = SearchString(_Patches[i].PtrToOriginalString + offset,
|
||||
pSectionHdrOfrdata->SizeOfRawData - (_Patches[i].PtrToOriginalString - pSectionOfrdata) - offset,
|
||||
PublicKeyPem.data() + ptr,
|
||||
Keywords[i].Length);
|
||||
|
||||
if (off == -1)
|
||||
return false;
|
||||
else
|
||||
offset += off;
|
||||
|
||||
uintptr_t Rva =
|
||||
pSectionHdrOfrdata->VirtualAddress +
|
||||
(_Patches[i].PtrToOriginalString - pSectionOfrdata) + // OriginalString Rva
|
||||
offset;
|
||||
|
||||
if (_TargetFile.IsRvaRangeInRelocationTable(Rva, Keywords[i].Length + 1) == false)
|
||||
break;
|
||||
else
|
||||
++offset;
|
||||
}
|
||||
|
||||
_Patches[i].PtrToReplaceString = _Patches[i].PtrToOriginalString + offset;
|
||||
}
|
||||
ptr += Keywords[i].Length;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PatchSolution3::MakePatch(RSACipher* pCipher) const {
|
||||
std::string PublicKeyPem = pCipher->ExportKeyString<RSACipher::KeyType::PublicKey,
|
||||
RSACipher::KeyFormat::PEM>();
|
||||
|
||||
PublicKeyPem.erase(PublicKeyPem.find("-----BEGIN PUBLIC KEY-----"), 26);
|
||||
PublicKeyPem.erase(PublicKeyPem.find("-----END PUBLIC KEY-----"), 24);
|
||||
{
|
||||
std::string::size_type pos = 0;
|
||||
while ((pos = PublicKeyPem.find("\n", pos)) != std::string::npos) {
|
||||
PublicKeyPem.erase(pos, 1);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t* pFileView = _TargetFile.GetImageBaseView<uint8_t>();
|
||||
|
||||
_putts(TEXT("******************************************"));
|
||||
_putts(TEXT("* PatchSulution3 *"));
|
||||
_putts(TEXT("******************************************"));
|
||||
|
||||
size_t ptr = 0;
|
||||
for (size_t i = 0; i < KeywordsCount; ++i) {
|
||||
_tprintf_s(TEXT("@ +%08zx: "), _Patches[i].PtrToPatch - pFileView);
|
||||
Helper::PrintSomeBytes(_Patches[i].PtrToPatch, _Patches[i].PatchSize);
|
||||
|
||||
_tprintf_s(TEXT(" ---> "));
|
||||
if (Keywords[i].NotRecommendedToModify == false) {
|
||||
memcpy(_Patches[i].PtrToPatch, PublicKeyPem.data() + ptr, Keywords[i].Length);
|
||||
} else {
|
||||
auto offset = _Patches[i].PtrToReplaceString - _Patches[i].PtrToOriginalString;
|
||||
|
||||
union {
|
||||
uint8_t bytes[8];
|
||||
uint64_t qword;
|
||||
} disp = {};
|
||||
|
||||
memcpy(disp.bytes, _Patches[i].PtrToPatch, _Patches[i].PatchSize);
|
||||
disp.qword += offset;
|
||||
memcpy(_Patches[i].PtrToPatch, disp.bytes, _Patches[i].PatchSize);
|
||||
}
|
||||
ptr += Keywords[i].Length;
|
||||
|
||||
Helper::PrintSomeBytes(_Patches[i].PtrToPatch, _Patches[i].PatchSize);
|
||||
_tprintf_s(TEXT("\n"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+144
-155
@@ -1,10 +1,15 @@
|
||||
#pragma once
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/pem.h>
|
||||
|
||||
#include "ExceptionOpenssl.hpp"
|
||||
#include "ResourceGuardOpenssl.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <memory.h>
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
#pragma comment(lib, "libcryptoMTd.lib")
|
||||
@@ -14,20 +19,11 @@
|
||||
#pragma comment(lib, "WS2_32.lib") // some symbol are used in OpenSSL static lib
|
||||
#pragma comment(lib, "Crypt32.lib") // some symbol are used in OpenSSL static lib
|
||||
|
||||
#undef __BASE_FILE__
|
||||
#define __BASE_FILE__ "RSACipher.hpp"
|
||||
|
||||
class RSACipher {
|
||||
private:
|
||||
RSA * _RsaObj;
|
||||
|
||||
RSACipher() : _RsaObj(nullptr) {}
|
||||
RSACipher(RSA* lpRsa) : _RsaObj(lpRsa) {}
|
||||
|
||||
RSACipher(const RSACipher&) = delete;
|
||||
RSACipher(RSACipher&&) = delete;
|
||||
RSACipher& operator=(const RSACipher&) = delete;
|
||||
RSACipher& operator=(RSACipher&&) = delete;
|
||||
|
||||
public:
|
||||
|
||||
enum class KeyType {
|
||||
PrivateKey,
|
||||
PublicKey
|
||||
@@ -38,229 +34,222 @@ public:
|
||||
PEM,
|
||||
PKCS1
|
||||
};
|
||||
private:
|
||||
ResourceGuard<OpensslRSATraits> _RsaObj;
|
||||
|
||||
~RSACipher() {
|
||||
if (_RsaObj)
|
||||
RSA_free(_RsaObj);
|
||||
_RsaObj = nullptr;
|
||||
RSACipher(RSA* pRsa) : _RsaObj(pRsa) {}
|
||||
|
||||
// Copy constructor is not allowed
|
||||
RSACipher(const RSACipher&) = delete;
|
||||
|
||||
// Copy assignment is not allowed
|
||||
RSACipher& operator=(const RSACipher&) = delete;
|
||||
|
||||
template<KeyType _Type, KeyFormat _Format = KeyFormat::NotSpecified>
|
||||
static void _RSAToBIO(RSA* pRsaObject, BIO* pBioObject) {
|
||||
if constexpr (_Type == KeyType::PrivateKey) {
|
||||
if (!PEM_write_bio_RSAPrivateKey(pBioObject, pRsaObject, nullptr, nullptr, 0, nullptr, nullptr))
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"PEM_write_bio_RSAPrivateKey fails.");
|
||||
} else {
|
||||
if constexpr (_Format == KeyFormat::PEM) {
|
||||
if (!PEM_write_bio_RSA_PUBKEY(pBioObject, pRsaObject))
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"PEM_write_bio_RSA_PUBKEY fails.");
|
||||
} else if constexpr (_Format == KeyFormat::PKCS1) {
|
||||
if (!PEM_write_bio_RSAPublicKey(pBioObject, pRsaObject))
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"PEM_write_bio_RSAPublicKey fails.");
|
||||
} else {
|
||||
static_assert(_Format == KeyFormat::PEM || _Format == KeyFormat::PKCS1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<KeyType _Type, KeyFormat _Format = KeyFormat::NotSpecified>
|
||||
static RSA* _BIOToRSA(BIO* pBioObject) {
|
||||
RSA* pNewRsaObject;
|
||||
|
||||
if constexpr (_Type == KeyType::PrivateKey) {
|
||||
pNewRsaObject = PEM_read_bio_RSAPrivateKey(pBioObject, nullptr, nullptr, nullptr);
|
||||
if (pNewRsaObject == nullptr)
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"PEM_read_bio_RSAPrivateKey fails.");
|
||||
} else {
|
||||
if constexpr (_Format == KeyFormat::PEM) {
|
||||
pNewRsaObject = PEM_read_bio_RSA_PUBKEY(pBioObject, nullptr, nullptr, nullptr);
|
||||
if (pNewRsaObject == nullptr)
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"PEM_read_bio_RSA_PUBKEY fails.");
|
||||
} else if constexpr (_Format == KeyFormat::PKCS1) {
|
||||
pNewRsaObject = PEM_read_bio_RSAPublicKey(pBioObject, nullptr, nullptr, nullptr);
|
||||
if (pNewRsaObject == nullptr)
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"PEM_read_bio_RSAPublicKey fails.");
|
||||
} else {
|
||||
static_assert(_Format == KeyFormat::PEM || _Format == KeyFormat::PKCS1);
|
||||
}
|
||||
}
|
||||
|
||||
return pNewRsaObject;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
static RSACipher* Create() {
|
||||
RSACipher* aCipher = new RSACipher(RSA_new());
|
||||
if (aCipher->_RsaObj == nullptr) {
|
||||
if (aCipher->_RsaObj.IsValid() == false) {
|
||||
delete aCipher;
|
||||
aCipher = nullptr;
|
||||
}
|
||||
return aCipher;
|
||||
}
|
||||
|
||||
bool GenerateKey(int bits, unsigned long long e = RSA_F4) {
|
||||
bool bSuccess = false;
|
||||
BIGNUM* bn_e = nullptr;
|
||||
RSACipher() : _RsaObj(RSA_new()) {
|
||||
if (_RsaObj.IsValid() == false)
|
||||
throw OpensslError(__BASE_FILE__, __LINE__, ERR_get_error(),
|
||||
"RSA_new fails.");
|
||||
}
|
||||
|
||||
bn_e = BN_new();
|
||||
if (bn_e == nullptr)
|
||||
goto ON_RSACipher_GenerateKey0_ERROR;
|
||||
void GenerateKey(int bits, unsigned int e = RSA_F4) {
|
||||
ResourceGuard<OpensslBNTraits> bn_e;
|
||||
|
||||
bn_e.TakeHoldOf(BN_new());
|
||||
if (bn_e.IsValid() == false)
|
||||
throw OpensslError(__BASE_FILE__, __LINE__, ERR_get_error(),
|
||||
"BN_new fails.");
|
||||
|
||||
if (!BN_set_word(bn_e, e))
|
||||
goto ON_RSACipher_GenerateKey0_ERROR;
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"BN_set_word fails.");
|
||||
|
||||
if (!RSA_generate_key_ex(_RsaObj, bits, bn_e, nullptr))
|
||||
goto ON_RSACipher_GenerateKey0_ERROR;
|
||||
|
||||
bSuccess = true;
|
||||
|
||||
ON_RSACipher_GenerateKey0_ERROR:
|
||||
if (bn_e)
|
||||
BN_free(bn_e);
|
||||
return bSuccess;
|
||||
throw OpensslError(__BASE_FILE__, __LINE__, ERR_get_error(),
|
||||
"RSA_generate_key_ex fails.");
|
||||
}
|
||||
|
||||
template<KeyType _Type, KeyFormat _Format = KeyFormat::NotSpecified>
|
||||
bool ExportKeyToFile(const std::string& filename) {
|
||||
static_assert(
|
||||
_Type == KeyType::PrivateKey || (_Format == KeyFormat::PEM || _Format == KeyFormat::PKCS1),
|
||||
"Not supported format."
|
||||
);
|
||||
void ExportKeyToFile(const std::string& FileName) {
|
||||
ResourceGuard<OpensslBIOTraits> bio_file;
|
||||
|
||||
bool bSuccess = false;
|
||||
BIO* bio_file = nullptr;
|
||||
bio_file.TakeHoldOf(BIO_new_file(FileName.c_str(), "w"));
|
||||
if (bio_file.IsValid() == false)
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"BIO_new_file fails.");
|
||||
|
||||
bio_file = BIO_new_file(filename.c_str(), "w");
|
||||
if (bio_file == nullptr)
|
||||
goto ON_RSACipher_ExportKeyToFile_0_ERROR;
|
||||
|
||||
if (_Type == KeyType::PrivateKey) {
|
||||
bSuccess = PEM_write_bio_RSAPrivateKey(bio_file, _RsaObj, nullptr, nullptr, 0, nullptr, nullptr) ? true : false;
|
||||
} else {
|
||||
if (_Format == KeyFormat::PEM)
|
||||
bSuccess = PEM_write_bio_RSA_PUBKEY(bio_file, _RsaObj) ? true : false;
|
||||
else if (_Format == KeyFormat::PKCS1)
|
||||
bSuccess = PEM_write_bio_RSAPublicKey(bio_file, _RsaObj) ? true : false;
|
||||
}
|
||||
|
||||
ON_RSACipher_ExportKeyToFile_0_ERROR:
|
||||
return bSuccess;
|
||||
_RSAToBIO<_Type, _Format>(_RsaObj, bio_file);
|
||||
}
|
||||
|
||||
template<KeyType _Type, KeyFormat _Format = KeyFormat::NotSpecified>
|
||||
std::string ExportKeyString() {
|
||||
static_assert(
|
||||
_Type == KeyType::PrivateKey || (_Format == KeyFormat::PEM || _Format == KeyFormat::PKCS1),
|
||||
"Not supported format."
|
||||
);
|
||||
std::string result;
|
||||
ResourceGuard<OpensslBIOTraits> bio_mem;
|
||||
int DataSize;
|
||||
const char* pData = nullptr;
|
||||
|
||||
std::string KeyString;
|
||||
BIO* bio_mem = nullptr;
|
||||
int len = 0;
|
||||
const char* lpdata = nullptr;
|
||||
bio_mem.TakeHoldOf(BIO_new(BIO_s_mem()));
|
||||
if (bio_mem.IsValid() == false)
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"BIO_new fails.");
|
||||
|
||||
bio_mem = BIO_new(BIO_s_mem());
|
||||
if (bio_mem == nullptr)
|
||||
goto ON_RSACipher_ExportKeyString_0_ERROR;
|
||||
_RSAToBIO<_Type, _Format>(_RsaObj, bio_mem);
|
||||
|
||||
if (_Type == KeyType::PrivateKey) {
|
||||
if (!PEM_write_bio_RSAPrivateKey(bio_mem, _RsaObj, nullptr, nullptr, 0, nullptr, nullptr))
|
||||
goto ON_RSACipher_ExportKeyString_0_ERROR;
|
||||
} else {
|
||||
if (_Format == KeyFormat::PEM) {
|
||||
if (!PEM_write_bio_RSA_PUBKEY(bio_mem, _RsaObj))
|
||||
goto ON_RSACipher_ExportKeyString_0_ERROR;
|
||||
} else if (_Format == KeyFormat::PKCS1) {
|
||||
if (!PEM_write_bio_RSAPublicKey(bio_mem, _RsaObj))
|
||||
goto ON_RSACipher_ExportKeyString_0_ERROR;
|
||||
}
|
||||
}
|
||||
DataSize = BIO_get_mem_data(bio_mem, &pData);
|
||||
result.resize(DataSize);
|
||||
memcpy(result.data(), pData, DataSize);
|
||||
|
||||
len = BIO_get_mem_data(bio_mem, &lpdata);
|
||||
|
||||
KeyString.resize(len);
|
||||
memcpy(KeyString.data(), lpdata, len);
|
||||
|
||||
ON_RSACipher_ExportKeyString_0_ERROR:
|
||||
if (bio_mem)
|
||||
BIO_free_all(bio_mem);
|
||||
return KeyString;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<KeyType _Type, KeyFormat _Format = KeyFormat::NotSpecified>
|
||||
bool ImportKeyFromFile(const std::string& filename) {
|
||||
static_assert(
|
||||
_Type == KeyType::PrivateKey || (_Format == KeyFormat::PEM || _Format == KeyFormat::PKCS1),
|
||||
"Not supported format."
|
||||
);
|
||||
|
||||
void ImportKeyFromFile(const std::string& FileName) {
|
||||
bool bSuccess = false;
|
||||
BIO* bio_file = nullptr;
|
||||
RSA* _newRsaObj = nullptr;
|
||||
ResourceGuard<OpensslBIOTraits> bio_file;
|
||||
RSA* NewRsaObj;
|
||||
|
||||
bio_file = BIO_new_file(filename.c_str(), "r");
|
||||
if (bio_file == nullptr)
|
||||
goto ON_RSACipher_ImportKeyFromFile_0_ERROR;
|
||||
bio_file.TakeHoldOf(BIO_new_file(FileName.c_str(), "r"));
|
||||
if (bio_file.IsValid() == false)
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"BIO_new_file fails.");
|
||||
|
||||
if (_Type == KeyType::PrivateKey) {
|
||||
_newRsaObj = PEM_read_bio_RSAPrivateKey(bio_file, nullptr, nullptr, nullptr);
|
||||
} else {
|
||||
if (_Format == KeyFormat::PEM)
|
||||
_newRsaObj = PEM_read_bio_RSA_PUBKEY(bio_file, nullptr, nullptr, nullptr);
|
||||
else if (_Format == KeyFormat::PKCS1)
|
||||
_newRsaObj = PEM_read_bio_RSAPublicKey(bio_file, nullptr, nullptr, nullptr);
|
||||
}
|
||||
|
||||
if (_newRsaObj) {
|
||||
RSA_free(_RsaObj);
|
||||
_RsaObj = _newRsaObj;
|
||||
bSuccess = true;
|
||||
}
|
||||
|
||||
ON_RSACipher_ImportKeyFromFile_0_ERROR:
|
||||
if (bio_file)
|
||||
BIO_free_all(bio_file);
|
||||
return bSuccess;
|
||||
NewRsaObj = _BIOToRSA<_Type, _Format>(bio_file);
|
||||
_RsaObj.Release();
|
||||
_RsaObj.TakeHoldOf(NewRsaObj);
|
||||
}
|
||||
|
||||
template<KeyType _Type, KeyFormat _Format = KeyFormat::NotSpecified>
|
||||
bool ImportKeyString(const std::string& KeyString) {
|
||||
static_assert(
|
||||
_Type == KeyType::PrivateKey || (_Format == KeyFormat::PEM || _Format == KeyFormat::PKCS1),
|
||||
"Not supported format."
|
||||
);
|
||||
|
||||
bool bSuccess = false;
|
||||
BIO* bio_mem = nullptr;
|
||||
RSA* _newRsaObj = nullptr;
|
||||
void ImportKeyString(const std::string& KeyString) {
|
||||
ResourceGuard<OpensslBIOTraits> bio_mem;
|
||||
RSA* NewRsaObj;
|
||||
|
||||
bio_mem = BIO_new(BIO_s_mem());
|
||||
if (bio_mem == nullptr)
|
||||
goto ON_RSACipher_ImportKeyString_0_ERROR;
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"BIO_new fails.");
|
||||
|
||||
BIO_puts(bio_mem, KeyString.c_str());
|
||||
if (BIO_puts(bio_mem, KeyString.c_str()) <= 0)
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"BIO_puts fails.");
|
||||
|
||||
if (_Type == KeyType::PrivateKey) {
|
||||
_newRsaObj = PEM_read_bio_RSAPrivateKey(bio_mem, nullptr, nullptr, nullptr);
|
||||
} else {
|
||||
if (_Format == KeyFormat::PEM)
|
||||
_newRsaObj = PEM_read_bio_RSA_PUBKEY(bio_mem, nullptr, nullptr, nullptr);
|
||||
else if (_Format == KeyFormat::PKCS1)
|
||||
_newRsaObj = PEM_read_bio_RSAPublicKey(bio_mem, nullptr, nullptr, nullptr);
|
||||
}
|
||||
|
||||
if (_newRsaObj) {
|
||||
RSA_free(_RsaObj);
|
||||
_RsaObj = _newRsaObj;
|
||||
bSuccess = true;
|
||||
}
|
||||
|
||||
ON_RSACipher_ImportKeyString_0_ERROR:
|
||||
if (bio_mem)
|
||||
BIO_free_all(bio_mem);
|
||||
return bSuccess;
|
||||
NewRsaObj = _BIOToRSA<_Type, _Format>(bio_mem);
|
||||
_RsaObj.Release();
|
||||
_RsaObj.TakeHoldOf(NewRsaObj);
|
||||
}
|
||||
|
||||
template<KeyType _Type = KeyType::PublicKey>
|
||||
int Encrypt(const void* from, int len, void* to, int padding) {
|
||||
int write_bytes = 0;
|
||||
int write_bytes;
|
||||
|
||||
if (_Type == KeyType::PrivateKey) {
|
||||
if constexpr (_Type == KeyType::PrivateKey) {
|
||||
write_bytes = RSA_private_encrypt(len,
|
||||
reinterpret_cast<const unsigned char*>(from),
|
||||
reinterpret_cast<unsigned char*>(to),
|
||||
_RsaObj,
|
||||
padding);
|
||||
if (write_bytes == -1)
|
||||
throw OpensslError(__BASE_FILE__, __LINE__, ERR_get_error(),
|
||||
"RSA_private_encrypt fails.");
|
||||
} else {
|
||||
write_bytes = RSA_public_encrypt(len,
|
||||
reinterpret_cast<const unsigned char*>(from),
|
||||
reinterpret_cast<unsigned char*>(to),
|
||||
_RsaObj,
|
||||
padding);
|
||||
if (write_bytes == -1)
|
||||
throw OpensslError(__BASE_FILE__, __LINE__, ERR_get_error(),
|
||||
"RSA_public_encrypt fails.");
|
||||
}
|
||||
|
||||
if (write_bytes == -1)
|
||||
write_bytes = 0;
|
||||
return write_bytes;
|
||||
}
|
||||
|
||||
template<KeyType _Type = KeyType::PrivateKey>
|
||||
int Decrypt(const void* from, int len, void* to, int padding) {
|
||||
int write_bytes = 0;
|
||||
int write_bytes;
|
||||
|
||||
if (_Type == KeyType::PrivateKey) {
|
||||
if constexpr (_Type == KeyType::PrivateKey) {
|
||||
write_bytes = RSA_private_decrypt(len,
|
||||
reinterpret_cast<const unsigned char*>(from),
|
||||
reinterpret_cast<unsigned char*>(to),
|
||||
_RsaObj,
|
||||
padding);
|
||||
if (write_bytes == -1)
|
||||
throw OpensslError(__BASE_FILE__, __LINE__, ERR_get_error(),
|
||||
"RSA_private_decrypt fails.");
|
||||
} else {
|
||||
write_bytes = RSA_public_decrypt(len,
|
||||
reinterpret_cast<const unsigned char*>(from),
|
||||
reinterpret_cast<unsigned char*>(to),
|
||||
_RsaObj,
|
||||
padding);
|
||||
if (write_bytes == -1)
|
||||
throw OpensslError(__BASE_FILE__, __LINE__, ERR_get_error(),
|
||||
"RSA_public_decrypt fails.");
|
||||
}
|
||||
|
||||
if (write_bytes == -1)
|
||||
write_bytes = 0;
|
||||
return write_bytes;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
#pragma once
|
||||
|
||||
template<typename __ResourceTraits>
|
||||
class ResourceGuard {
|
||||
private:
|
||||
using HandleType = typename __ResourceTraits::HandleType;
|
||||
HandleType _Handle;
|
||||
bool _DismissFlag;
|
||||
public:
|
||||
|
||||
ResourceGuard() noexcept :
|
||||
_Handle(__ResourceTraits::InvalidValue),
|
||||
_DismissFlag(false) {}
|
||||
|
||||
explicit ResourceGuard(HandleType Handle) :
|
||||
_Handle(Handle),
|
||||
_DismissFlag(false) {}
|
||||
|
||||
ResourceGuard(const ResourceGuard<__ResourceTraits>& Other) noexcept :
|
||||
_Handle(Other._Handle),
|
||||
_DismissFlag(false) {}
|
||||
|
||||
ResourceGuard(ResourceGuard<__ResourceTraits>&& Other) noexcept :
|
||||
_Handle(Other._Handle),
|
||||
_DismissFlag(false) { Other._Handle = __ResourceTraits::InvalidValue; }
|
||||
|
||||
ResourceGuard<__ResourceTraits>&
|
||||
operator=(const ResourceGuard<__ResourceTraits>& Other) noexcept {
|
||||
_Handle = Other._Handle;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ResourceGuard<__ResourceTraits>&
|
||||
operator=(ResourceGuard<__ResourceTraits>&& Other) noexcept {
|
||||
_Handle = Other._Handle;
|
||||
Other._Handle = __ResourceTraits::InvalidValue;
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator HandleType() const noexcept {
|
||||
return _Handle;
|
||||
}
|
||||
|
||||
// Check if handle is a valid handle
|
||||
bool IsValid() const noexcept {
|
||||
return _Handle != __ResourceTraits::InvalidValue;
|
||||
}
|
||||
|
||||
HandleType GetHandle() const noexcept {
|
||||
return _Handle;
|
||||
}
|
||||
|
||||
// Abandon possession of the previous handle without any conditions
|
||||
// You must make sure that the previous handle has been released
|
||||
// OR has been possessed by others
|
||||
void TakeHoldOf(HandleType Handle) noexcept {
|
||||
_Handle = Handle;
|
||||
}
|
||||
|
||||
// If dismiss, the handle won't be released when ResourceGuard is destructed.
|
||||
void Dismiss() noexcept {
|
||||
_DismissFlag = true;
|
||||
}
|
||||
|
||||
// Cancel Dismiss() operation
|
||||
void DismissCancel() noexcept {
|
||||
_DismissFlag = false;
|
||||
}
|
||||
|
||||
// Force release
|
||||
void Release() {
|
||||
if (_Handle != __ResourceTraits::InvalidValue) {
|
||||
__ResourceTraits::Releasor(_Handle);
|
||||
_Handle = __ResourceTraits::InvalidValue;
|
||||
}
|
||||
}
|
||||
|
||||
~ResourceGuard() {
|
||||
if (!_DismissFlag && _Handle != __ResourceTraits::InvalidValue) {
|
||||
__ResourceTraits::Releasor(_Handle);
|
||||
_Handle = __ResourceTraits::InvalidValue;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename __ClassType>
|
||||
struct CppObjectTraits {
|
||||
using HandleType = __ClassType*;
|
||||
static inline const HandleType InvalidValue = nullptr;
|
||||
static inline void Releasor(HandleType pObject) {
|
||||
delete pObject;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename __ClassType>
|
||||
struct CppDynamicArrayTraits {
|
||||
using HandleType = __ClassType*;
|
||||
static inline const HandleType InvalidValue = nullptr;
|
||||
static inline void Releasor(HandleType pArray) {
|
||||
delete[] pArray;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#include "ResourceGuard.hpp"
|
||||
|
||||
#if defined(CAPSTONE_ENGINE_H)
|
||||
|
||||
struct CapstoneHandleTraits {
|
||||
using HandleType = csh;
|
||||
static inline const HandleType InvalidValue = 0;
|
||||
static inline void Releasor(HandleType Handle) {
|
||||
cs_close(&Handle);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename __Type>
|
||||
struct CapstoneMallocTraits {
|
||||
using HandleType = __Type*;
|
||||
static inline const HandleType InvalidValue = nullptr;
|
||||
static inline void Releasor(HandleType Handle) {
|
||||
cs_free(Handle, 1);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
#include "ResourceGuard.hpp"
|
||||
|
||||
#if defined(HEADER_BIO_H)
|
||||
|
||||
struct OpensslBIOTraits {
|
||||
using HandleType = BIO*;
|
||||
static inline const HandleType InvalidValue = nullptr;
|
||||
static constexpr auto& Releasor = BIO_free;
|
||||
};
|
||||
|
||||
|
||||
struct OpensslBIOChainTraits {
|
||||
using HandleType = BIO*;
|
||||
static inline const HandleType InvalidValue = nullptr;
|
||||
static constexpr auto& Releasor = BIO_free_all;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(HEADER_BN_H)
|
||||
|
||||
struct OpensslBNTraits {
|
||||
using HandleType = BIGNUM*;
|
||||
static inline const HandleType InvalidValue = nullptr;
|
||||
static constexpr auto& Releasor = BN_free;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(HEADER_RSA_H)
|
||||
|
||||
struct OpensslRSATraits {
|
||||
using HandleType = RSA*;
|
||||
static inline const HandleType InvalidValue = nullptr;
|
||||
static constexpr auto& Releasor = RSA_free;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
#include "ResourceGuard.hpp"
|
||||
|
||||
#if defined(_WINDOWS_)
|
||||
|
||||
struct GenericHandleTraits {
|
||||
using HandleType = HANDLE;
|
||||
static inline const HandleType InvalidValue = NULL;
|
||||
static constexpr auto& Releasor = CloseHandle;
|
||||
};
|
||||
|
||||
struct FileHandleTraits {
|
||||
using HandleType = HANDLE;
|
||||
static inline const HandleType InvalidValue = INVALID_HANDLE_VALUE;
|
||||
static constexpr auto& Releasor = CloseHandle;
|
||||
};
|
||||
|
||||
struct MapViewTraits {
|
||||
using HandleType = PVOID;
|
||||
static inline const HandleType InvalidValue = NULL;
|
||||
static constexpr auto& Releasor = UnmapViewOfFile;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,285 +0,0 @@
|
||||
#include "def.hpp"
|
||||
|
||||
// Solution0 is for navicat premium of which the version < 12.0.25
|
||||
namespace patcher::Solution0 {
|
||||
|
||||
static std::Tstring InstallationPath;
|
||||
|
||||
static const CHAR Keyword[] =
|
||||
"-----BEGIN PUBLIC KEY-----\r\n"
|
||||
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw1dqF3SkCaAAmMzs889I\r\n"
|
||||
"qdW9M2dIdh3jG9yPcmLnmJiGpBF4E9VHSMGe8oPAy2kJDmdNt4BcEygvssEfginv\r\n"
|
||||
"a5t5jm352UAoDosUJkTXGQhpAWMF4fBmBpO3EedG62rOsqMBgmSdAyxCSPBRJIOF\r\n"
|
||||
"R0QgZFbRnU0frj34fiVmgYiLuZSAmIbs8ZxiHPdp1oD4tUpvsFci4QJtYNjNnGU2\r\n"
|
||||
"WPH6rvChGl1IRKrxMtqLielsvajUjyrgOC6NmymYMvZNER3htFEtL1eQbCyTfDmt\r\n"
|
||||
"YyQ1Wt4Ot12lxf0wVIR5mcGN7XCXJRHOFHSf1gzXWabRSvmt1nrl7sW6cjxljuuQ\r\n"
|
||||
"awIDAQAB\r\n"
|
||||
"-----END PUBLIC KEY-----\r\n";
|
||||
|
||||
static const DWORD KeywordLength = sizeof(Keyword) - 1;
|
||||
|
||||
static LPCTSTR PossibleName[3] = {
|
||||
TEXT("Navicat.exe"), // for Linux compatible, main program name is "Navicat.exe" in Linux, case sensitive
|
||||
TEXT("Modeler.exe"), // for Linux compatible
|
||||
TEXT("Rviewer.exe") // for Linux compatible
|
||||
};
|
||||
|
||||
static LPCTSTR TargetName = NULL;
|
||||
|
||||
static HMODULE hTarget = NULL;
|
||||
|
||||
BOOL Init(const std::Tstring& Path) {
|
||||
BOOL bSuccess = FALSE;
|
||||
DWORD dwLastError = ERROR_SUCCESS;
|
||||
DWORD attr = INVALID_FILE_ATTRIBUTES;
|
||||
|
||||
attr = GetFileAttributes(Path.c_str());
|
||||
if (attr == INVALID_FILE_ATTRIBUTES) {
|
||||
dwLastError = GetLastError();
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("Failed @ GetFileAttributes. CODE: 0x%08X\n"), dwLastError);
|
||||
goto ON_Init_ERROR;
|
||||
}
|
||||
|
||||
if ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("Error: Path is not a directory.\n"));
|
||||
goto ON_Init_ERROR;
|
||||
}
|
||||
|
||||
InstallationPath = Path;
|
||||
if (InstallationPath.back() != TEXT('\\') && InstallationPath.back() != TEXT('/'))
|
||||
InstallationPath.push_back(TEXT('/')); // for Linux compatible
|
||||
|
||||
bSuccess = TRUE;
|
||||
|
||||
ON_Init_ERROR:
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
BOOL CheckKey(RSACipher* cipher) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL FindTargetFile() {
|
||||
BOOL bSuccess = FALSE;
|
||||
DWORD dwLastError = ERROR_SUCCESS;
|
||||
|
||||
for (size_t i = 0; i < _countof(PossibleName); ++i) {
|
||||
std::Tstring&& PossibleFileName = InstallationPath + PossibleName[i];
|
||||
|
||||
hTarget = LoadLibrary(PossibleFileName.c_str());
|
||||
if (hTarget == NULL && (dwLastError = GetLastError()) != ERROR_MOD_NOT_FOUND) {
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("Unexpected Error @ LoadLibrary. CODE: 0x%08X\n"), dwLastError);
|
||||
goto ON_FindTargetFile_ERROR;
|
||||
}
|
||||
if (hTarget) {
|
||||
_tprintf_s(TEXT("Target has been found: %s\n"), PossibleName[i]);
|
||||
TargetName = PossibleName[i];
|
||||
bSuccess = TRUE;
|
||||
goto ON_FindTargetFile_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
ON_FindTargetFile_ERROR:
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
BOOL CheckFile() {
|
||||
BOOL bFound = FALSE;
|
||||
DWORD dwLastError = ERROR_SUCCESS;
|
||||
HRSRC hRes = NULL;
|
||||
HGLOBAL hGLobal = NULL;
|
||||
PVOID lpData = NULL;
|
||||
DWORD dwSize = 0;
|
||||
|
||||
if (hTarget == NULL) {
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("Error: Target has not been set yet.\n"));
|
||||
goto ON_CheckFile_ERROR;
|
||||
}
|
||||
|
||||
hRes = FindResource(hTarget, TEXT("ACTIVATIONPUBKEY"), RT_RCDATA);
|
||||
if (hRes == NULL) {
|
||||
dwLastError = GetLastError();
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("Failed @ FindResource. CODE: 0x%08X\n"), dwLastError);
|
||||
goto ON_CheckFile_ERROR;
|
||||
}
|
||||
|
||||
hGLobal = LoadResource(hTarget, hRes);
|
||||
if (hGLobal == NULL) {
|
||||
dwLastError = GetLastError();
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("Failed @ LoadResource. CODE: 0x%08X\n"), dwLastError);
|
||||
goto ON_CheckFile_ERROR;
|
||||
}
|
||||
|
||||
lpData = LockResource(hGLobal);
|
||||
if (lpData == NULL) {
|
||||
dwLastError = GetLastError();
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("Failed @ LockResource. CODE: 0x%08X\n"), dwLastError);
|
||||
goto ON_CheckFile_ERROR;
|
||||
}
|
||||
|
||||
dwSize = SizeofResource(hTarget, hRes);
|
||||
if (dwSize == 0) {
|
||||
dwLastError = GetLastError();
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("Failed @ SizeofResource. CODE: 0x%08X\n"), dwLastError);
|
||||
goto ON_CheckFile_ERROR;
|
||||
}
|
||||
|
||||
if (dwSize == KeywordLength && memcmp(lpData, Keyword, KeywordLength) == 0) {
|
||||
FreeLibrary(hTarget);
|
||||
hTarget = NULL;
|
||||
bFound = TRUE;
|
||||
} else {
|
||||
FreeLibrary(hTarget);
|
||||
hTarget = NULL;
|
||||
TargetName = NULL;
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("ERROR: Resource doest not match.\n"));
|
||||
goto ON_CheckFile_ERROR;
|
||||
}
|
||||
|
||||
ON_CheckFile_ERROR:
|
||||
return bFound;
|
||||
}
|
||||
|
||||
BOOL BackupFile() {
|
||||
BOOL bSuccess = FALSE;
|
||||
DWORD dwLastError = ERROR_SUCCESS;
|
||||
std::Tstring&& TargetFileName = InstallationPath + TargetName;
|
||||
std::Tstring&& BackupFileName = InstallationPath + TargetName + TEXT(".backup");
|
||||
|
||||
if (!CopyFile(TargetFileName.c_str(), BackupFileName.c_str(), TRUE)) {
|
||||
dwLastError = GetLastError();
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("Failed @ CopyFile. CODE: 0x%08X\n"), dwLastError);
|
||||
goto ON_BackupFile_ERROR;
|
||||
}
|
||||
|
||||
bSuccess = TRUE;
|
||||
ON_BackupFile_ERROR:
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
BOOL Do(RSACipher* cipher) {
|
||||
BOOL bSuccess = FALSE;
|
||||
DWORD dwLastError = ERROR_SUCCESS;
|
||||
std::string RSAPublicKeyPEM;
|
||||
std::Tstring&& TargetFileName = InstallationPath + TargetName;
|
||||
HANDLE hUpdater = NULL;
|
||||
|
||||
RSAPublicKeyPEM = cipher->ExportKeyString<RSACipher::KeyType::PublicKey, RSACipher::KeyFormat::PEM>();
|
||||
if (RSAPublicKeyPEM.empty()) {
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("ERROR: cipher->ExportKeyString failed.\n"));
|
||||
goto ON_Do_ERROR;
|
||||
}
|
||||
|
||||
[](std::string& str, const std::string& OldSub, const std::string& NewSub) {
|
||||
std::string::size_type pos = 0;
|
||||
std::string::size_type srclen = OldSub.size();
|
||||
std::string::size_type dstlen = NewSub.size();
|
||||
|
||||
while ((pos = str.find(OldSub, pos)) != std::string::npos) {
|
||||
str.replace(pos, srclen, NewSub);
|
||||
pos += dstlen;
|
||||
}
|
||||
} (RSAPublicKeyPEM, "\n", "\r\n"); // replace '\n' to '\r\n'
|
||||
|
||||
if (RSAPublicKeyPEM.length() != KeywordLength) {
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("ERROR: Public key length does not match.\n"));
|
||||
goto ON_Do_ERROR;
|
||||
}
|
||||
|
||||
hUpdater = BeginUpdateResource(TargetFileName.c_str(), FALSE);
|
||||
if (hUpdater == NULL) {
|
||||
dwLastError = GetLastError();
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("Failed @ BeginUpdateResource. CODE: 0x%08X\n"), dwLastError);
|
||||
goto ON_Do_ERROR;
|
||||
}
|
||||
|
||||
if (!UpdateResource(hUpdater,
|
||||
RT_RCDATA,
|
||||
TEXT("ACTIVATIONPUBKEY"),
|
||||
MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
|
||||
(LPVOID)RSAPublicKeyPEM.c_str(),
|
||||
KeywordLength)) {
|
||||
dwLastError = GetLastError();
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("Failed @ UpdateResource. CODE: 0x%08X\n"), dwLastError);
|
||||
goto ON_Do_ERROR;
|
||||
}
|
||||
|
||||
bSuccess = TRUE;
|
||||
|
||||
ON_Do_ERROR:
|
||||
EndUpdateResource(hUpdater, !bSuccess);
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
BOOL GetVersion(LPDWORD lpMajorVer, LPDWORD lpMinorVer) {
|
||||
BOOL bSuccess = FALSE;
|
||||
DWORD dwLastError = ERROR_SUCCESS;
|
||||
std::Tstring&& TargetFileName = InstallationPath + TargetName;
|
||||
DWORD dwSize = 0;
|
||||
PVOID lpData = NULL;
|
||||
VS_FIXEDFILEINFO* lpVersionInfo = NULL;
|
||||
UINT VersionInfoSize = 0;
|
||||
|
||||
dwSize = GetFileVersionInfoSize(TargetFileName.c_str(),
|
||||
&dwSize); // MSDN doesn't say it can be NULL.
|
||||
// so I use dwSize to receive this deprecated value
|
||||
if (dwSize == 0) {
|
||||
dwLastError = GetLastError();
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("Failed @ GetFileVersionInfoSize. CODE: 0x%08X\n"), dwLastError);
|
||||
goto ON_GetVersion_ERROR;
|
||||
}
|
||||
|
||||
lpData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
|
||||
if (lpData == NULL) {
|
||||
dwLastError = GetLastError();
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("Failed @ HeapAlloc. CODE: 0x%08X\n"), dwLastError);
|
||||
goto ON_GetVersion_ERROR;
|
||||
}
|
||||
|
||||
if (!GetFileVersionInfo(TargetFileName.c_str(), NULL, dwSize, lpData)) {
|
||||
dwLastError = GetLastError();
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("Failed @ GetFileVersionInfo. CODE: 0x%08X\n"), dwLastError);
|
||||
goto ON_GetVersion_ERROR;
|
||||
}
|
||||
|
||||
if (!VerQueryValue(lpData, TEXT("\\"), (LPVOID*)&lpVersionInfo, &VersionInfoSize)) {
|
||||
dwLastError = GetLastError();
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("Failed @ VerQueryValue. CODE: 0x%08X\n"), dwLastError);
|
||||
goto ON_GetVersion_ERROR;
|
||||
}
|
||||
|
||||
*lpMajorVer = lpVersionInfo->dwProductVersionMS;
|
||||
*lpMinorVer = lpVersionInfo->dwProductVersionLS;
|
||||
bSuccess = TRUE;
|
||||
|
||||
ON_GetVersion_ERROR:
|
||||
if (lpData)
|
||||
HeapFree(GetProcessHeap(), NULL, lpData);
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
VOID Finalize() {
|
||||
if (hTarget) {
|
||||
FreeLibrary(hTarget);
|
||||
hTarget = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,417 +0,0 @@
|
||||
#include "def.hpp"
|
||||
|
||||
// Solution1 is for navicat premium of which the version = 12.0.25
|
||||
namespace patcher::Solution1 {
|
||||
|
||||
static std::Tstring InstallationPath;
|
||||
|
||||
static const CHAR Keyword0[] =
|
||||
"D75125B70767B94145B47C1CB3C0755E"
|
||||
"7CCB8825C5DCE0C58ACF944E08280140"
|
||||
"9A02472FAFFD1CD77864BB821AE36766"
|
||||
"FEEDE6A24F12662954168BFA314BD950"
|
||||
"32B9D82445355ED7BC0B880887D650F5";
|
||||
|
||||
static const DWORD KeywordSize0 = sizeof(Keyword0) - 1;
|
||||
|
||||
static const uint8_t Keyword1[] = {
|
||||
0xFE, 0xEA, 0xBC, 0x01
|
||||
};
|
||||
|
||||
static const DWORD KeywordSize1 = sizeof(Keyword1);
|
||||
|
||||
static const CHAR Keyword2[] =
|
||||
"E1CED09B9C2186BF71A70C0FE2F1E0AE"
|
||||
"F3BD6B75277AAB20DFAF3D110F75912B"
|
||||
"FB63AC50EC4C48689D1502715243A79F"
|
||||
"39FF2DE2BF15CE438FF885745ED54573"
|
||||
"850E8A9F40EE2FF505EB7476F95ADB78"
|
||||
"3B28CA374FAC4632892AB82FB3BF4715"
|
||||
"FCFE6E82D03731FC3762B6AAC3DF1C3B"
|
||||
"C646FE9CD3C62663A97EE72DB932A301"
|
||||
"312B4A7633100C8CC357262C39A2B3A6"
|
||||
"4B224F5276D5EDBDF0804DC3AC4B8351"
|
||||
"62BB1969EAEBADC43D2511D6E0239287"
|
||||
"81B167A48273B953378D3D2080CC0677"
|
||||
"7E8A2364F0234B81064C5C739A8DA28D"
|
||||
"C5889072BF37685CBC94C2D31D0179AD"
|
||||
"86D8E3AA8090D4F0B281BE37E0143746"
|
||||
"E6049CCC06899401264FA471C016A96C"
|
||||
"79815B55BBC26B43052609D9D175FBCD"
|
||||
"E455392F10E51EC162F51CF732E6BB39"
|
||||
"1F56BBFD8D957DF3D4C55B71CEFD54B1"
|
||||
"9C16D458757373E698D7E693A8FC3981"
|
||||
"5A8BF03BA05EA8C8778D38F9873D62B4"
|
||||
"460F41ACF997C30E7C3AF025FA171B5F"
|
||||
"5AD4D6B15E95C27F6B35AD61875E5505"
|
||||
"449B4E";
|
||||
|
||||
static const DWORD KeywordSize2 = sizeof(Keyword2) - 1;
|
||||
|
||||
static const uint8_t Keyword3[] = {
|
||||
0x59, 0x08, 0x01, 0x00
|
||||
};
|
||||
|
||||
static const DWORD KeywordSize3 = sizeof(Keyword3);
|
||||
|
||||
static const CHAR Keyword4[] = "92933";
|
||||
|
||||
static const DWORD KeywordSize4 = sizeof(Keyword4) - 1;
|
||||
|
||||
static DWORD KeywordOffset[5] = { -1, -1, -1, -1, -1 };
|
||||
|
||||
static LPCTSTR TargetName = TEXT("libcc.dll");
|
||||
|
||||
static HANDLE hTarget = INVALID_HANDLE_VALUE;
|
||||
static HANDLE hTargetMap = NULL;
|
||||
static PVOID lpFileContent = NULL;
|
||||
|
||||
BOOL Init(const std::Tstring& Path) {
|
||||
BOOL bSuccess = FALSE;
|
||||
DWORD dwLastError = ERROR_SUCCESS;
|
||||
DWORD attr = INVALID_FILE_ATTRIBUTES;
|
||||
|
||||
attr = GetFileAttributes(Path.c_str());
|
||||
if (attr == INVALID_FILE_ATTRIBUTES) {
|
||||
dwLastError = GetLastError();
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("Failed @ GetFileAttributes. CODE: 0x%08X\n"), dwLastError);
|
||||
goto ON_Init_ERROR;
|
||||
}
|
||||
|
||||
if ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("Error: Path is not a directory.\n"));
|
||||
goto ON_Init_ERROR;
|
||||
}
|
||||
|
||||
InstallationPath = Path;
|
||||
if (InstallationPath.back() != TEXT('\\') && InstallationPath.back() != TEXT('/'))
|
||||
InstallationPath.push_back(TEXT('/')); // for Linux compatible
|
||||
|
||||
bSuccess = TRUE;
|
||||
|
||||
ON_Init_ERROR:
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
BOOL CheckKey(RSACipher* cipher) {
|
||||
BOOL bOk = FALSE;
|
||||
std::string RSAPublicKeyPEM;
|
||||
|
||||
RSAPublicKeyPEM = cipher->ExportKeyString<RSACipher::KeyType::PublicKey, RSACipher::KeyFormat::PEM>();
|
||||
if (RSAPublicKeyPEM.empty()) {
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("ERROR: cipher->ExportKeyString failed.\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
[](std::string& str, const std::string& OldSub, const std::string& NewSub) {
|
||||
std::string::size_type pos = 0;
|
||||
std::string::size_type srclen = OldSub.size();
|
||||
std::string::size_type dstlen = NewSub.size();
|
||||
|
||||
while ((pos = str.find(OldSub, pos)) != std::string::npos) {
|
||||
str.replace(pos, srclen, NewSub);
|
||||
pos += dstlen;
|
||||
}
|
||||
} (RSAPublicKeyPEM, "\n", "\r\n"); // replace '\n' to '\r\n'
|
||||
|
||||
std::string encrypted_pem_text = EncryptPublicKey(RSAPublicKeyPEM.c_str(),
|
||||
RSAPublicKeyPEM.length());
|
||||
|
||||
if (encrypted_pem_text[160] > '9' || encrypted_pem_text[160] < '1')
|
||||
return FALSE;
|
||||
|
||||
for (int i = 1; i < 8; ++i)
|
||||
if (encrypted_pem_text[160 + i] > '9' || encrypted_pem_text[160 + i] < '0')
|
||||
return FALSE;
|
||||
|
||||
if (encrypted_pem_text[910] > '9' || encrypted_pem_text[910] < '1')
|
||||
return FALSE;
|
||||
|
||||
for (int i = 1; i < 5; ++i)
|
||||
if (encrypted_pem_text[910 + i] > '9' || encrypted_pem_text[910 + i] < '0')
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static PIMAGE_SECTION_HEADER ImageSectionHeader(PVOID lpBase, LPCSTR lpSectionName) {
|
||||
IMAGE_DOS_HEADER* pFileHeader = NULL;
|
||||
IMAGE_NT_HEADERS* pNtHeader = NULL;
|
||||
IMAGE_SECTION_HEADER* pSectionHeaders = NULL;
|
||||
|
||||
pFileHeader = (IMAGE_DOS_HEADER*)lpBase;
|
||||
if (pFileHeader->e_magic != IMAGE_DOS_SIGNATURE)
|
||||
return NULL;
|
||||
|
||||
pNtHeader = (IMAGE_NT_HEADERS*)((BYTE*)lpBase + pFileHeader->e_lfanew);
|
||||
if (pNtHeader->Signature != IMAGE_NT_SIGNATURE)
|
||||
return NULL;
|
||||
|
||||
pSectionHeaders = (IMAGE_SECTION_HEADER*)((BYTE*)pNtHeader +
|
||||
offsetof(IMAGE_NT_HEADERS, OptionalHeader) +
|
||||
pNtHeader->FileHeader.SizeOfOptionalHeader);
|
||||
for (WORD i = 0; i < pNtHeader->FileHeader.NumberOfSections; ++i)
|
||||
if (_stricmp((const char*)pSectionHeaders[i].Name, lpSectionName) == 0)
|
||||
return pSectionHeaders + i;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL FindTargetFile() {
|
||||
DWORD dwLastError = ERROR_SUCCESS;
|
||||
std::Tstring&& TargetFileName = InstallationPath + TargetName;
|
||||
|
||||
hTarget = CreateFile(TargetFileName.c_str(),
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
if (hTarget == INVALID_HANDLE_VALUE) {
|
||||
dwLastError = GetLastError();
|
||||
if (dwLastError == ERROR_FILE_NOT_FOUND) {
|
||||
return FALSE;
|
||||
} else {
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("Unexpected Error @ CreateFile. CODE: 0x%08X\n"), dwLastError);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL FindOffset() {
|
||||
BOOL bSuccess = FALSE;
|
||||
DWORD dwLastError = ERROR_SUCCESS;
|
||||
IMAGE_SECTION_HEADER* textSection = NULL;
|
||||
IMAGE_SECTION_HEADER* rdataSection = NULL;
|
||||
|
||||
hTargetMap = CreateFileMapping(hTarget,
|
||||
NULL,
|
||||
PAGE_READWRITE,
|
||||
0,
|
||||
0,
|
||||
NULL);
|
||||
if (hTargetMap == NULL) {
|
||||
dwLastError = GetLastError();
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("Failed @ CreateFileMapping. CODE: 0x%08X\n"), dwLastError);
|
||||
goto ON_FindOffset_ERROR;
|
||||
}
|
||||
|
||||
lpFileContent = MapViewOfFile(hTargetMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
|
||||
if (lpFileContent == NULL) {
|
||||
dwLastError = GetLastError();
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("Failed @ MapViewOfFile. CODE: 0x%08X\n"), dwLastError);
|
||||
goto ON_FindOffset_ERROR;
|
||||
}
|
||||
|
||||
textSection = ImageSectionHeader(lpFileContent, ".text");
|
||||
if (textSection == NULL) {
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("ERROR: Cannot find .text section.\n"));
|
||||
goto ON_FindOffset_ERROR;
|
||||
}
|
||||
|
||||
rdataSection = ImageSectionHeader(lpFileContent, ".rdata");
|
||||
if (textSection == NULL) {
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("ERROR: Cannot find .rdata section.\n"));
|
||||
goto ON_FindOffset_ERROR;
|
||||
}
|
||||
|
||||
// -------------------------
|
||||
// try to search keyword0
|
||||
// -------------------------
|
||||
for (DWORD i = 0; i < rdataSection->SizeOfRawData; ++i) {
|
||||
if (memcmp((uint8_t*)lpFileContent + rdataSection->PointerToRawData + i, Keyword0, KeywordSize0) == 0) {
|
||||
KeywordOffset[0] = rdataSection->PointerToRawData + i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (KeywordOffset[0] == -1) {
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("ERROR: Cannot find Keyword0.\n"));
|
||||
goto ON_FindOffset_ERROR;
|
||||
} else {
|
||||
_tprintf_s(TEXT("Keyword0 has been found: offset = +0x%08X.\n"), KeywordOffset[0]);
|
||||
}
|
||||
|
||||
// -------------------------
|
||||
// try to search keyword1
|
||||
// -------------------------
|
||||
for (DWORD i = 0; i < textSection->SizeOfRawData; ++i) {
|
||||
if (memcmp((uint8_t*)lpFileContent + textSection->PointerToRawData + i, Keyword1, KeywordSize1) == 0) {
|
||||
KeywordOffset[1] = textSection->PointerToRawData + i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (KeywordOffset[1] == -1) {
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("ERROR: Cannot find Keyword1.\n"));
|
||||
goto ON_FindOffset_ERROR;
|
||||
} else {
|
||||
_tprintf_s(TEXT("Keyword1 has been found: offset = +0x%08X.\n"), KeywordOffset[1]);
|
||||
}
|
||||
|
||||
// -------------------------
|
||||
// try to search keyword2
|
||||
// -------------------------
|
||||
for (DWORD i = 0; i < rdataSection->SizeOfRawData; ++i) {
|
||||
if (memcmp((uint8_t*)lpFileContent + rdataSection->PointerToRawData + i, Keyword2, KeywordSize2) == 0) {
|
||||
KeywordOffset[2] = rdataSection->PointerToRawData + i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (KeywordOffset[2] == -1) {
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("ERROR: Cannot find Keyword2.\n"));
|
||||
goto ON_FindOffset_ERROR;
|
||||
} else {
|
||||
_tprintf_s(TEXT("Keyword2 has been found: offset = +0x%08X.\n"), KeywordOffset[2]);
|
||||
}
|
||||
|
||||
// -------------------------
|
||||
// try to search keyword3
|
||||
// -------------------------
|
||||
for (DWORD i = 0; i < textSection->SizeOfRawData; ++i) {
|
||||
if (memcmp((uint8_t*)lpFileContent + textSection->PointerToRawData + i, Keyword3, KeywordSize3) == 0) {
|
||||
KeywordOffset[3] = textSection->PointerToRawData + i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (KeywordOffset[3] == -1) {
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("ERROR: Cannot find Keyword3.\n"));
|
||||
goto ON_FindOffset_ERROR;
|
||||
} else {
|
||||
_tprintf_s(TEXT("Keyword3 has been found: offset = +0x%08X.\n"), KeywordOffset[3]);
|
||||
}
|
||||
|
||||
// -------------------------
|
||||
// try to search keyword4
|
||||
// -------------------------
|
||||
for (DWORD i = 0; i < rdataSection->SizeOfRawData; ++i) {
|
||||
if (memcmp((uint8_t*)lpFileContent + rdataSection->PointerToRawData + i, Keyword4, KeywordSize4) == 0) {
|
||||
KeywordOffset[4] = rdataSection->PointerToRawData + i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (KeywordOffset[4] == -1) {
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("ERROR: Cannot find Keyword4.\n"));
|
||||
goto ON_FindOffset_ERROR;
|
||||
} else {
|
||||
_tprintf_s(TEXT("Keyword4 has been found: offset = +0x%08X.\n"), KeywordOffset[4]);
|
||||
}
|
||||
|
||||
bSuccess = TRUE;
|
||||
|
||||
ON_FindOffset_ERROR:
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
BOOL BackupFile() {
|
||||
BOOL bSuccess = FALSE;
|
||||
DWORD dwLastError = ERROR_SUCCESS;
|
||||
std::Tstring&& TargetFileName = InstallationPath + TargetName;
|
||||
std::Tstring&& BackupFileName = InstallationPath + TargetName + TEXT(".backup");
|
||||
|
||||
if (!CopyFile(TargetFileName.c_str(), BackupFileName.c_str(), TRUE)) {
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("Failed @ CopyFile. CODE: 0x%08X\n"), dwLastError);
|
||||
goto ON_BackupFile_ERROR;
|
||||
}
|
||||
|
||||
bSuccess = TRUE;
|
||||
ON_BackupFile_ERROR:
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
BOOL Do(RSACipher* cipher) {
|
||||
std::string RSAPublicKeyPEM;
|
||||
std::string encrypted_pem_pubkey;
|
||||
|
||||
RSAPublicKeyPEM = cipher->ExportKeyString<RSACipher::KeyType::PublicKey, RSACipher::KeyFormat::PEM>();
|
||||
if (RSAPublicKeyPEM.empty()) {
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("ERROR: cipher->ExportKeyString failed.\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
[](std::string& str, const std::string& OldSub, const std::string& NewSub) {
|
||||
std::string::size_type pos = 0;
|
||||
std::string::size_type srclen = OldSub.size();
|
||||
std::string::size_type dstlen = NewSub.size();
|
||||
|
||||
while ((pos = str.find(OldSub, pos)) != std::string::npos) {
|
||||
str.replace(pos, srclen, NewSub);
|
||||
pos += dstlen;
|
||||
}
|
||||
} (RSAPublicKeyPEM, "\n", "\r\n"); // replace '\n' to '\r\n'
|
||||
|
||||
encrypted_pem_pubkey = EncryptPublicKey(RSAPublicKeyPEM.c_str(), RSAPublicKeyPEM.length());
|
||||
|
||||
// split encrypted_pem_pubkey to 5 part: |160 chars|8 chars|742 chars|5 chars|5 chars|
|
||||
// | |
|
||||
// \ / \ /
|
||||
// imm1 imm3
|
||||
std::string encrypted_pem_pubkey0(encrypted_pem_pubkey.begin(), encrypted_pem_pubkey.begin() + 160);
|
||||
std::string encrypted_pem_pubkey1(encrypted_pem_pubkey.begin() + 160, encrypted_pem_pubkey.begin() + 160 + 8);
|
||||
std::string encrypted_pem_pubkey2(encrypted_pem_pubkey.begin() + 160 + 8, encrypted_pem_pubkey.begin() + 160 + 8 + 742);
|
||||
std::string encrypted_pem_pubkey3(encrypted_pem_pubkey.begin() + 160 + 8 + 742, encrypted_pem_pubkey.begin() + 160 + 8 + 742 + 5);
|
||||
std::string encrypted_pem_pubkey4(encrypted_pem_pubkey.begin() + 160 + 8 + 742 + 5, encrypted_pem_pubkey.end());
|
||||
uint32_t imm1 = std::stoul(encrypted_pem_pubkey1.c_str());
|
||||
uint32_t imm3 = std::stoul(encrypted_pem_pubkey3.c_str());
|
||||
|
||||
_tprintf_s(TEXT("\n"));
|
||||
_tprintf_s(TEXT("@Offset +0x%08X, write string:\n"), KeywordOffset[0]);
|
||||
printf_s("\"%s\"\n\n", encrypted_pem_pubkey0.c_str());
|
||||
memcpy((uint8_t*)lpFileContent + KeywordOffset[0], encrypted_pem_pubkey0.c_str(), 160);
|
||||
|
||||
_tprintf_s(TEXT("@Offset +0x%08X, write uint32_t:\n"), KeywordOffset[1]);
|
||||
printf_s("0x%08X\n\n", imm1);
|
||||
memcpy((uint8_t*)lpFileContent + KeywordOffset[1], &imm1, sizeof(uint32_t));
|
||||
|
||||
_tprintf_s(TEXT("@Offset +0x%08X, write string:\n"), KeywordOffset[2]);
|
||||
printf_s("\"%s\"\n\n", encrypted_pem_pubkey2.c_str());
|
||||
memcpy((uint8_t*)lpFileContent + KeywordOffset[2], encrypted_pem_pubkey2.c_str(), 742);
|
||||
|
||||
_tprintf_s(TEXT("@Offset +0x%08X, write uint32_t:\n"), KeywordOffset[3]);
|
||||
printf_s("0x%08X\n\n", imm3);
|
||||
memcpy((uint8_t*)lpFileContent + KeywordOffset[3], &imm3, sizeof(uint32_t));
|
||||
|
||||
_tprintf_s(TEXT("@Offset +0x%08X, write string:\n"), KeywordOffset[4]);
|
||||
printf_s("\"%s\"\n\n", encrypted_pem_pubkey4.c_str());
|
||||
memcpy((uint8_t*)lpFileContent + KeywordOffset[4], encrypted_pem_pubkey4.c_str(), 5);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID Finalize() {
|
||||
if (lpFileContent) {
|
||||
UnmapViewOfFile(lpFileContent);
|
||||
lpFileContent = NULL;
|
||||
}
|
||||
if (hTargetMap) {
|
||||
CloseHandle(hTargetMap);
|
||||
hTargetMap = NULL;
|
||||
}
|
||||
if (hTarget) {
|
||||
CloseHandle(hTarget);
|
||||
hTarget = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+312
-149
@@ -1,188 +1,351 @@
|
||||
#include "def.hpp"
|
||||
#include <tchar.h>
|
||||
#include <windows.h>
|
||||
#include "Exception.hpp"
|
||||
#include "PatchSolution.hpp"
|
||||
#include "Helper.hpp"
|
||||
|
||||
bool ConvertToUTF8(LPCSTR from, std::string& to) {
|
||||
bool bSuccess = false;
|
||||
int len = 0;
|
||||
LPWSTR lpUnicodeString = nullptr;
|
||||
#undef __BASE_FILE__
|
||||
#define __BASE_FILE__ "_tmain.cpp"
|
||||
|
||||
len = MultiByteToWideChar(CP_ACP, NULL, from, -1, NULL, 0);
|
||||
if (len == 0)
|
||||
goto ON_ConvertToUTF8_0_ERROR;
|
||||
#define PRINT_MESSAGE_LITERAL(m) _putts(TEXT(m))
|
||||
#define PRINT_PTSTR(m) _putts(m)
|
||||
#define PRINT_PCSTR(m) puts(m)
|
||||
#define PRINT_PCWSTR(m) _putws(m)
|
||||
|
||||
lpUnicodeString = reinterpret_cast<LPWSTR>(HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
len * sizeof(WCHAR)));
|
||||
if (lpUnicodeString == nullptr)
|
||||
goto ON_ConvertToUTF8_0_ERROR;
|
||||
String InstallationPath;
|
||||
String MainAppName;
|
||||
String LibccName = TEXT("libcc.dll");
|
||||
|
||||
if (!MultiByteToWideChar(CP_ACP, NULL, from, -1, lpUnicodeString, len))
|
||||
goto ON_ConvertToUTF8_0_ERROR;
|
||||
|
||||
len = WideCharToMultiByte(CP_UTF8, NULL, lpUnicodeString, -1, NULL, 0, NULL, NULL);
|
||||
if (len == 0)
|
||||
goto ON_ConvertToUTF8_0_ERROR;
|
||||
|
||||
to.resize(len);
|
||||
if (!WideCharToMultiByte(CP_UTF8, NULL, lpUnicodeString, -1, to.data(), len, NULL, NULL))
|
||||
goto ON_ConvertToUTF8_0_ERROR;
|
||||
|
||||
while (to.back() == 0)
|
||||
to.pop_back();
|
||||
|
||||
bSuccess = true;
|
||||
|
||||
ON_ConvertToUTF8_0_ERROR:
|
||||
if (lpUnicodeString)
|
||||
HeapFree(GetProcessHeap(), NULL, lpUnicodeString);
|
||||
return bSuccess;
|
||||
static void Welcome() {
|
||||
PRINT_MESSAGE_LITERAL("***************************************************");
|
||||
PRINT_MESSAGE_LITERAL("* Navicat Patcher by @DoubleLabyrinth *");
|
||||
_tprintf_s(TEXT("* Release date: %-24s*\n"), TEXT(__DATE__));
|
||||
PRINT_MESSAGE_LITERAL("***************************************************");
|
||||
PRINT_MESSAGE_LITERAL("");
|
||||
PRINT_MESSAGE_LITERAL("Press Enter to continue or Ctrl + C to abort.");
|
||||
_gettchar();
|
||||
}
|
||||
|
||||
bool ConvertToUTF8(LPCWSTR from, std::string& to) {
|
||||
bool bSuccess = false;
|
||||
int len = 0;
|
||||
|
||||
len = WideCharToMultiByte(CP_UTF8, NULL, from, -1, NULL, 0, NULL, NULL);
|
||||
if (len == 0)
|
||||
goto ON_ConvertToUTF8_1_ERROR;
|
||||
|
||||
to.resize(len);
|
||||
if (!WideCharToMultiByte(CP_UTF8, NULL, from, -1, to.data(), len, NULL, NULL))
|
||||
goto ON_ConvertToUTF8_1_ERROR;
|
||||
|
||||
while (to.back() == 0)
|
||||
to.pop_back();
|
||||
|
||||
bSuccess = true;
|
||||
|
||||
ON_ConvertToUTF8_1_ERROR:
|
||||
return bSuccess;
|
||||
static void Help() {
|
||||
PRINT_MESSAGE_LITERAL("Usage:");
|
||||
PRINT_MESSAGE_LITERAL(" navicat-patcher.exe <Navicat installation path> [RSA-2048 PEM file]");
|
||||
}
|
||||
|
||||
bool ConvertToUTF8(std::string& str) {
|
||||
bool bSuccess = false;
|
||||
static void SetPath(PTSTR pszPath) {
|
||||
DWORD Attr;
|
||||
|
||||
std::string temp;
|
||||
bSuccess = ConvertToUTF8(str.c_str(), temp);
|
||||
if (!bSuccess)
|
||||
return false;
|
||||
Attr = GetFileAttributes(pszPath);
|
||||
if (Attr == INVALID_FILE_ATTRIBUTES)
|
||||
throw SystemError(__BASE_FILE__, __LINE__, GetLastError(),
|
||||
"GetFileAttributes fails.");
|
||||
|
||||
str = temp;
|
||||
return true;
|
||||
if ((Attr & FILE_ATTRIBUTE_DIRECTORY) == 0)
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"Path does not point to a directory.");
|
||||
|
||||
InstallationPath = pszPath;
|
||||
if (InstallationPath.back() != TEXT('\\') && InstallationPath.back() != TEXT('/'))
|
||||
InstallationPath.push_back(TEXT('/')); // for Linux compatible
|
||||
}
|
||||
|
||||
int _tmain(int argc, TCHAR* argv[]) {
|
||||
static void BackupFile(const String& From, const String& To) {
|
||||
if (::CopyFile(From.c_str(), To.c_str(), TRUE) == FALSE)
|
||||
throw SystemError(__BASE_FILE__, __LINE__, GetLastError(),
|
||||
"CopyFile fails.");
|
||||
}
|
||||
|
||||
static void LoadKey(RSACipher* pCipher, PTSTR FileName,
|
||||
PatchSolution* pSolution0,
|
||||
PatchSolution* pSolution1,
|
||||
PatchSolution* pSolution2,
|
||||
PatchSolution* pSolution3) {
|
||||
if (FileName) {
|
||||
std::string PrivateKeyFileName = Helper::ConvertToUTF8(FileName);
|
||||
|
||||
pCipher->ImportKeyFromFile<RSACipher::KeyType::PrivateKey, RSACipher::KeyFormat::PEM>(PrivateKeyFileName);
|
||||
|
||||
if (pSolution0 && !pSolution0->CheckKey(pCipher) ||
|
||||
pSolution1 && !pSolution1->CheckKey(pCipher) ||
|
||||
pSolution2 && !pSolution2->CheckKey(pCipher) ||
|
||||
pSolution3 && !pSolution3->CheckKey(pCipher))
|
||||
throw Exception(__BASE_FILE__, __LINE__,
|
||||
"The RSA private key you provide cannot be used.");
|
||||
} else {
|
||||
PRINT_MESSAGE_LITERAL("MESSAGE: Generating new RSA private key, it may take a long time.");
|
||||
|
||||
do {
|
||||
pCipher->GenerateKey(2048);
|
||||
} while (pSolution0 && !pSolution0->CheckKey(pCipher) ||
|
||||
pSolution1 && !pSolution1->CheckKey(pCipher) ||
|
||||
pSolution2 && !pSolution2->CheckKey(pCipher) ||
|
||||
pSolution3 && !pSolution3->CheckKey(pCipher)); // re-generate RSA key if CheckKey return false
|
||||
|
||||
pCipher->ExportKeyToFile<RSACipher::KeyType::PrivateKey, RSACipher::KeyFormat::NotSpecified>("RegPrivateKey.pem");
|
||||
|
||||
PRINT_MESSAGE_LITERAL("MESSAGE: New RSA private key has been saved to RegPrivateKey.pem.");
|
||||
}
|
||||
|
||||
std::string PublicKeyString = pCipher->ExportKeyString<RSACipher::KeyType::PublicKey, RSACipher::KeyFormat::PEM>();
|
||||
|
||||
PRINT_MESSAGE_LITERAL("");
|
||||
PRINT_MESSAGE_LITERAL("Your RSA public key:");
|
||||
PRINT_PCSTR(PublicKeyString.c_str());
|
||||
}
|
||||
|
||||
static void ExceptionReport(const Exception& e) noexcept {
|
||||
printf_s("ERROR: @ %s - Line %d\n", e.SourceFile(), e.SourceLine());
|
||||
if (e.HasErrorCode()) {
|
||||
const char* aa = e.ErrorString();
|
||||
printf_s("ErrorCode = 0x%08lx\n", e.ErrorCode());
|
||||
printf_s("ErrorString: %s\n", e.ErrorString());
|
||||
} else {
|
||||
printf_s("%s\n", e.CustomMessage());
|
||||
}
|
||||
}
|
||||
|
||||
int _tmain(int argc, PTSTR argv[]) {
|
||||
if (argc != 2 && argc != 3) {
|
||||
_tprintf_s(TEXT("Usage:\n"));
|
||||
_tprintf_s(TEXT(" navicat-patcher.exe <Navicat installation path> [RSA-2048 PEM file]\n"));
|
||||
Help();
|
||||
return 0;
|
||||
}
|
||||
|
||||
RSACipher* cipher = NULL;
|
||||
DWORD dwMajorVer = 0;
|
||||
DWORD dwMinorVer = 0;
|
||||
Welcome();
|
||||
|
||||
cipher = RSACipher::Create();
|
||||
if (cipher == NULL) {
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("RSACipher::Create failed.\n"));
|
||||
goto ON_tmain_ERROR;
|
||||
ResourceGuard<CppObjectTraits<RSACipher>> pCipher;
|
||||
ResourceGuard<CppObjectTraits<FileMapper>> pMainExe;
|
||||
ResourceGuard<CppObjectTraits<FileMapper>> pLibccDLL;
|
||||
ResourceGuard<CppObjectTraits<PatchSolution>> pSolution0;
|
||||
ResourceGuard<CppObjectTraits<PatchSolution>> pSolution1;
|
||||
ResourceGuard<CppObjectTraits<PatchSolution>> pSolution2;
|
||||
ResourceGuard<CppObjectTraits<PatchSolution>> pSolution3;
|
||||
|
||||
try {
|
||||
SetPath(argv[1]);
|
||||
} catch (Exception& e) {
|
||||
ExceptionReport(e);
|
||||
PRINT_MESSAGE_LITERAL("Are you sure the path you specified is correct?");
|
||||
PRINT_MESSAGE_LITERAL("The path you specified:");
|
||||
PRINT_PTSTR(argv[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!patcher::Solution0::Init(argv[1]))
|
||||
goto ON_tmain_ERROR;
|
||||
if (!patcher::Solution1::Init(argv[1]))
|
||||
goto ON_tmain_ERROR;
|
||||
pCipher.TakeHoldOf(new RSACipher());
|
||||
|
||||
if (argc == 3) {
|
||||
std::string PrivateKeyFileName;
|
||||
// -----------------
|
||||
// Map files
|
||||
// -----------------
|
||||
do {
|
||||
pLibccDLL.TakeHoldOf(new FileMapper());
|
||||
try {
|
||||
pLibccDLL.GetHandle()->MapFile(InstallationPath + TEXT("libcc.dll"));
|
||||
break;
|
||||
} catch (Exception& e) {
|
||||
if (!e.HasErrorCode() || e.ErrorCode() != ERROR_FILE_NOT_FOUND) {
|
||||
ExceptionReport(e);
|
||||
if (e.HasErrorCode() && e.ErrorCode() == ERROR_ACCESS_DENIED)
|
||||
PRINT_MESSAGE_LITERAL("Please re-run with Administrator privilege.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
pLibccDLL.Release();
|
||||
|
||||
if (!ConvertToUTF8(argv[2], PrivateKeyFileName)) {
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("ERROR: ConvertToUTF8 failed.\n"));
|
||||
goto ON_tmain_ERROR;
|
||||
pMainExe.TakeHoldOf(new FileMapper());
|
||||
try {
|
||||
pMainExe.GetHandle()->MapFile(InstallationPath + TEXT("Navicat.exe"));
|
||||
MainAppName = TEXT("Navicat.exe");
|
||||
break;
|
||||
} catch (Exception& e) {
|
||||
if (!e.HasErrorCode() || e.ErrorCode() != ERROR_FILE_NOT_FOUND) {
|
||||
ExceptionReport(e);
|
||||
if (e.HasErrorCode() && e.ErrorCode() == ERROR_ACCESS_DENIED)
|
||||
PRINT_MESSAGE_LITERAL("Please re-run with Administrator privilege.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cipher->ImportKeyFromFile<RSACipher::KeyType::PrivateKey, RSACipher::KeyFormat::PEM>(PrivateKeyFileName)) {
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("ERROR: cipher->ImportKeyFromFile failed.\n"));
|
||||
goto ON_tmain_ERROR;
|
||||
try {
|
||||
pMainExe.GetHandle()->MapFile(InstallationPath + TEXT("Modeler.exe"));
|
||||
MainAppName = TEXT("Modeler.exe");
|
||||
break;
|
||||
} catch (Exception& e) {
|
||||
if (!e.HasErrorCode() || e.ErrorCode() != ERROR_FILE_NOT_FOUND) {
|
||||
ExceptionReport(e);
|
||||
if (e.HasErrorCode() && e.ErrorCode() == ERROR_ACCESS_DENIED)
|
||||
PRINT_MESSAGE_LITERAL("Please re-run with Administrator privilege.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (patcher::Solution0::CheckKey(cipher) == FALSE || patcher::Solution1::CheckKey(cipher) == FALSE) {
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("ERROR: RSA private key specified cannot be used.\n"));
|
||||
goto ON_tmain_ERROR;
|
||||
try {
|
||||
pMainExe.GetHandle()->MapFile(InstallationPath + TEXT("Rviewer.exe"));
|
||||
MainAppName = TEXT("Rviewer.exe");
|
||||
break;
|
||||
} catch (Exception& e) {
|
||||
if (!e.HasErrorCode() || e.ErrorCode() != ERROR_FILE_NOT_FOUND) {
|
||||
ExceptionReport(e);
|
||||
if (e.HasErrorCode() && e.ErrorCode() == ERROR_ACCESS_DENIED)
|
||||
PRINT_MESSAGE_LITERAL("Please re-run with Administrator privilege.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
pMainExe.Release();
|
||||
} while (false);
|
||||
|
||||
// -----------
|
||||
// decide PatchSolutions
|
||||
// -----------
|
||||
|
||||
if (pMainExe.IsValid()) {
|
||||
try {
|
||||
pSolution0.TakeHoldOf(new PatchSolution0());
|
||||
pSolution0.GetHandle()->SetFile(pMainExe);
|
||||
if (pSolution0.GetHandle()->FindPatchOffset() == false) {
|
||||
PRINT_MESSAGE_LITERAL("MESSAGE: PatchSolution0 will be omitted.");
|
||||
pSolution0.Release();
|
||||
}
|
||||
PRINT_MESSAGE_LITERAL("");
|
||||
} catch (Exception& e) {
|
||||
ExceptionReport(e);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
_tprintf_s(TEXT("Generating new RSA private key, it may take long time.\n"));
|
||||
PRINT_MESSAGE_LITERAL("MESSAGE: PatchSolution0 will be omitted.");
|
||||
PRINT_MESSAGE_LITERAL("");
|
||||
}
|
||||
|
||||
do {
|
||||
cipher->GenerateKey(2048);
|
||||
} while (!patcher::Solution0::CheckKey(cipher) || !patcher::Solution1::CheckKey(cipher)); // re-generate RSA key if one of CheckKey return FALSE
|
||||
if (pLibccDLL.IsValid()) {
|
||||
try {
|
||||
pSolution3.TakeHoldOf(new PatchSolution3());
|
||||
pSolution3.GetHandle()->SetFile(pLibccDLL);
|
||||
if (pSolution3.GetHandle()->FindPatchOffset() == false) {
|
||||
PRINT_MESSAGE_LITERAL("MESSAGE: PatchSolution3 will be omitted.");
|
||||
pSolution3.Release();
|
||||
}
|
||||
PRINT_MESSAGE_LITERAL("");
|
||||
|
||||
if (!cipher->ExportKeyToFile<RSACipher::KeyType::PrivateKey, RSACipher::KeyFormat::NotSpecified>("RegPrivateKey.pem")) {
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("ERROR: Failed to save RSA private key.\n"));
|
||||
goto ON_tmain_ERROR;
|
||||
pSolution2.TakeHoldOf(new PatchSolution2());
|
||||
pSolution2.GetHandle()->SetFile(pLibccDLL);
|
||||
if (pSolution2.GetHandle()->FindPatchOffset() == false) {
|
||||
PRINT_MESSAGE_LITERAL("MESSAGE: PatchSolution2 will be omitted.");
|
||||
pSolution2.Release();
|
||||
}
|
||||
PRINT_MESSAGE_LITERAL("");
|
||||
|
||||
pSolution1.TakeHoldOf(new PatchSolution1());
|
||||
pSolution1.GetHandle()->SetFile(pLibccDLL);
|
||||
if (pSolution1.GetHandle()->FindPatchOffset() == false) {
|
||||
PRINT_MESSAGE_LITERAL("MESSAGE: PatchSolution1 will be omitted.");
|
||||
pSolution2.Release();
|
||||
}
|
||||
PRINT_MESSAGE_LITERAL("");
|
||||
} catch (Exception& e) {
|
||||
ExceptionReport(e);
|
||||
return 0;
|
||||
}
|
||||
|
||||
_tprintf_s(TEXT("New RSA private key has been saved to RegPrivateKey.pem.\n"));
|
||||
} else {
|
||||
PRINT_MESSAGE_LITERAL("MESSAGE: PatchSolution3 will be omitted.");
|
||||
PRINT_MESSAGE_LITERAL("MESSAGE: PatchSolution2 will be omitted.");
|
||||
PRINT_MESSAGE_LITERAL("MESSAGE: PatchSolution1 will be omitted.");
|
||||
PRINT_MESSAGE_LITERAL("");
|
||||
}
|
||||
|
||||
// ------------------
|
||||
// begin Solution0
|
||||
// ------------------
|
||||
if (!patcher::Solution0::FindTargetFile()) {
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("ERROR: Cannot find main program. Are you sure the path you specified is correct?\n"));
|
||||
goto ON_tmain_ERROR;
|
||||
if (pSolution0.IsValid() == false)
|
||||
pMainExe.Release();
|
||||
|
||||
if (pSolution1.IsValid() == false && pSolution2.IsValid() == false && pSolution3.IsValid() == false)
|
||||
pLibccDLL.Release();
|
||||
|
||||
if (pSolution0.IsValid() == false &&
|
||||
pSolution1.IsValid() == false &&
|
||||
pSolution2.IsValid() == false &&
|
||||
pSolution3.IsValid() == false)
|
||||
{
|
||||
PRINT_MESSAGE_LITERAL("");
|
||||
PRINT_MESSAGE_LITERAL("ERROR: Cannot find RSA public key.");
|
||||
PRINT_MESSAGE_LITERAL("Are you sure your Navicat has not been patched before?");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!patcher::Solution0::GetVersion(&dwMajorVer, &dwMinorVer))
|
||||
goto ON_tmain_ERROR;
|
||||
// -------------
|
||||
// LoadKey
|
||||
// -------------
|
||||
try {
|
||||
LoadKey(pCipher,
|
||||
argc == 3 ? argv[2] : nullptr,
|
||||
pSolution0,
|
||||
pSolution1,
|
||||
pSolution2,
|
||||
pSolution3);
|
||||
} catch (Exception& e) {
|
||||
ExceptionReport(e);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!patcher::Solution0::CheckFile())
|
||||
goto ON_tmain_ERROR;
|
||||
// -------------
|
||||
// BackupFile
|
||||
// -------------
|
||||
try {
|
||||
if (pMainExe.IsValid())
|
||||
BackupFile(InstallationPath + MainAppName, InstallationPath + MainAppName + TEXT(".backup"));
|
||||
} catch (Exception& e) {
|
||||
ExceptionReport(e);
|
||||
if (e.HasErrorCode() && e.ErrorCode() == ERROR_FILE_EXISTS) {
|
||||
_tprintf_s(TEXT("The backup of %s has been found.\n"), MainAppName.c_str());
|
||||
_tprintf_s(TEXT("Please remove %s.backup in Navicat installation path if you're sure %s has not been patched.\n"),
|
||||
MainAppName.c_str(),
|
||||
MainAppName.c_str());
|
||||
_tprintf_s(TEXT("Otherwise please restore %s by %s.backup and remove %s.backup then try again.\n"),
|
||||
MainAppName.c_str(),
|
||||
MainAppName.c_str(),
|
||||
MainAppName.c_str());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!patcher::Solution0::BackupFile())
|
||||
goto ON_tmain_ERROR;
|
||||
try {
|
||||
if (pLibccDLL.IsValid())
|
||||
BackupFile(InstallationPath + LibccName, InstallationPath + LibccName + TEXT(".backup"));
|
||||
} catch (Exception& e) {
|
||||
ExceptionReport(e);
|
||||
if (e.HasErrorCode() && e.ErrorCode() == ERROR_FILE_EXISTS) {
|
||||
_tprintf_s(TEXT("The backup of %s has been found.\n"), LibccName.c_str());
|
||||
_tprintf_s(TEXT("Please remove %s.backup in Navicat installation path if you're sure %s has not been patched.\n"),
|
||||
LibccName.c_str(),
|
||||
LibccName.c_str());
|
||||
_tprintf_s(TEXT("Otherwise please restore %s by %s.backup and remove %s.backup then try again.\n"),
|
||||
LibccName.c_str(),
|
||||
LibccName.c_str(),
|
||||
LibccName.c_str());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!patcher::Solution0::Do(cipher))
|
||||
goto ON_tmain_ERROR;
|
||||
// -------------
|
||||
// MakePatch
|
||||
// -------------
|
||||
try {
|
||||
if (pSolution3.IsValid()) {
|
||||
pSolution3.GetHandle()->MakePatch(pCipher);
|
||||
PRINT_MESSAGE_LITERAL("");
|
||||
}
|
||||
if (pSolution2.IsValid()) {
|
||||
pSolution2.GetHandle()->MakePatch(pCipher);
|
||||
PRINT_MESSAGE_LITERAL("");
|
||||
}
|
||||
if (pSolution1.IsValid()) {
|
||||
pSolution1.GetHandle()->MakePatch(pCipher);
|
||||
PRINT_MESSAGE_LITERAL("");
|
||||
}
|
||||
if (pSolution0.IsValid()) {
|
||||
pSolution0.GetHandle()->MakePatch(pCipher);
|
||||
PRINT_MESSAGE_LITERAL("");
|
||||
}
|
||||
} catch (Exception& e) {
|
||||
ExceptionReport(e);
|
||||
return 0;
|
||||
}
|
||||
|
||||
_tprintf_s(TEXT("RSA public key has been replaced by\n"));
|
||||
printf_s("%s\n", cipher->ExportKeyString<RSACipher::KeyType::PublicKey, RSACipher::KeyFormat::PEM>().c_str());
|
||||
_tprintf_s(TEXT("Solution0 has been done successfully.\n"));
|
||||
_tprintf_s(TEXT("\n"));
|
||||
|
||||
// for ver <= 12.0.24
|
||||
if (dwMajorVer == 0x000c0000 && dwMinorVer < 0x00180000)
|
||||
goto ON_tmain_ERROR; // you don't need Solution1 patch.
|
||||
|
||||
// ------------------
|
||||
// begin Solution1
|
||||
// ------------------
|
||||
if (!patcher::Solution1::FindTargetFile()) {
|
||||
_tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
|
||||
_tprintf_s(TEXT("ERROR: Cannot find libcc.dll. Are you sure the path you specified is correct?\n"));
|
||||
goto ON_tmain_ERROR;
|
||||
}
|
||||
|
||||
if (!patcher::Solution1::FindOffset())
|
||||
goto ON_tmain_ERROR;
|
||||
|
||||
if (!patcher::Solution1::BackupFile())
|
||||
goto ON_tmain_ERROR;
|
||||
|
||||
if (!patcher::Solution1::Do(cipher))
|
||||
goto ON_tmain_ERROR;
|
||||
|
||||
_tprintf_s(TEXT("Solution1 has been done successfully.\n"));
|
||||
_tprintf_s(TEXT("\n"));
|
||||
|
||||
ON_tmain_ERROR:
|
||||
patcher::Solution1::Finalize();
|
||||
patcher::Solution0::Finalize();
|
||||
delete cipher;
|
||||
PRINT_MESSAGE_LITERAL("MESSAGE: Patch has been done successfully.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user