BrainFuck转C语言小程序
本帖最后由 hrh123 于 2023-9-27 20:07 编辑# BrainFuck转C
## 前言
今天看到了帖子
> 记一次brainfuck的解密思路
> <https://www.52pojie.cn/thread-1441720-1-1.html>
> (出处: 吾爱破解论坛)
我居然才知道这语言竟然还能和脱壳破解挂上钩,这帖子里是将brainfuck转了python分析,我技术差,就转c,并稍微完善了下(相当于一个简单的解释器了)
~~本来想着和那贴一样发到脱壳破解区的,后来想想就这么简单个小程序就不碰瓷论坛技术大区了~~
## Brainfuck简介
它是一种是一种极小化的程序语言,一种简单的,可以用最小的编译器来实现的,符合图灵完全思想的编程语言,后缀*一般*为`.brainfuck`或`.bf`
它只有8个运算符,即
+ `>`或`<` : 指针加减1
+ `+`或`-` : 指针所指的字节的值加减1
+ `,`或`.` : 读取或输出指针所指字节内容(ASCII码)
+ `[`或`]` : 若指针所指字节的值为零,则向前/后跳转,跳转到其对应的`[`或`]`的下一个指令处
## 代码实现
### 实现命令行读取
这部分代码异常简单,我这里只有sys库提供的功能实现
```python
import sys
if len(sys.argv) == 1:
print(f"Usage: {sys.argv} input_file output_file")
sys.exit(1)
elif len(sys.argv) != 3 and len(sys.argv) != 2:
print("no input files")
sys.exit(1)
input_file = sys.argv
try:
output_file = sys.argv
except IndexError:
output_file = "a.c"
try:
with open(input_file, "r") as in_file:
program = in_file.read()
except IOError:
print(f"Cannot open input file: {input_file}")
sys.exit(2)
```
### 转化部分
根据刚才的对于运算符的解释,我们很容易得到它与c语言的对应关系,那么我先准备了一个字典,当然我这里使用了typing库来做了一些增加可读性的操作
```python
from typing import Dict, List
CHAR_TO_OUTPUT: Dict = {
">": "\t++ptr;\n",
"<": "\t--ptr;\n",
"+": "\t++*ptr;\n",
"-": "\t--*ptr;\n",
".": "\tputchar(*ptr);\n",
",": "\t*ptr = getchar();\n",
"[": "\twhile (*ptr) {\n",
"]": "\t}\n",
}
```
继续往下,我定义了一个列表来存放输出并添加必要的头文件和声明,以及定义一个长度为30000的字符数组`array`和一个指针`ptr`,用来模拟bf的内存空间
```python
output: List = []
output.append("#include <stdio.h>\n\n")
output.append("int main(void)\n")
output.append("{\n")
output.append("\tchar array = {0};\n")
output.append("\tchar *ptr = array;\n\n")
```
接下去,刚才已经定义好字典了,那我们只需简单的用循环来遍历bf的程序,并使用`CHAR_TO_OUTPUT`字典来获取对应的字符串,然后添加到`output`就好了
```python
for c in program:
if c in CHAR_TO_OUTPUT:
output.append(CHAR_TO_OUTPUT)
```
最后,添加一些必要的结束语句,并将列表中的元素用换行符连接起来就好了
```python
output.append("\n\treturn 0;\n")
output.append("}\n")
output_str = "\n".join(output)
```
### 结束
当然也不要忘了对输出文件做处理
```python
try:
with open(output_file, "w") as out_file:
out_file.write(output_str)
except IOError:
print(f"Cannot open output file: {output_file}")
sys.exit(3)
sys.exit(0)
```
## 示例
用一个简单的HelloWorld程序测试下
```brainfuck
++++++++++[>+++++++>++++++++++>+++>+<<<<-]
>++.>+.+++++++..+++.>++.<<+++++++++++++++.
>.+++.------.--------.>+.>.
```
来到终端
```text
PS \BrainFuck> python main.py hello.bf hello.c
PS \BrainFuck> gcc hello.c -o hello
PS \BrainFuck> ./hello
Hello World!
PS \BrainFuck>
```
测试成功!
## 完整代码
```python
import sys
from typing import Dict, List
CHAR_TO_OUTPUT: Dict = {
">": "\t++ptr;\n",
"<": "\t--ptr;\n",
"+": "\t++*ptr;\n",
"-": "\t--*ptr;\n",
".": "\tputchar(*ptr);\n",
",": "\t*ptr = getchar();\n",
"[": "\twhile (*ptr) {\n",
"]": "\t}\n",
}
if len(sys.argv) == 1:
print(f"Usage: {sys.argv} input_file output_file")
sys.exit(1)
elif len(sys.argv) != 3 and len(sys.argv) != 2:
print("no input files")
sys.exit(1)
input_file = sys.argv
try:
output_file = sys.argv
except IndexError:
output_file = "a.c"
try:
with open(input_file, "r") as in_file:
program = in_file.read()
except IOError:
print(f"Cannot open input file: {input_file}")
sys.exit(2)
output: List = []
output.append("#include <stdio.h>\n\n")
output.append("int main(void)\n")
output.append("{\n")
output.append("\tchar array = {0};\n")
output.append("\tchar *ptr = array;\n\n")
for c in program:
if c in CHAR_TO_OUTPUT:
output.append(CHAR_TO_OUTPUT)
output.append("\n\treturn 0;\n")
output.append("}\n")
output_str = "\n".join(output)
try:
with open(output_file, "w") as out_file:
out_file.write(output_str)
except IOError:
print(f"Cannot open output file: {output_file}")
sys.exit(3)
sys.exit(0)
``` 亲测有效。最近在重学c++,这样的程序还挺新鲜的
页:
[1]