吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1285|回复: 1
收起左侧

[Python 原创] BrainFuck转C语言小程序

[复制链接]
hrh123 发表于 2023-9-27 19:57
本帖最后由 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库提供的功能实现

import sys

if len(sys.argv) == 1:
    print(f"Usage: {sys.argv[0]} 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[1]
try:
    output_file = sys.argv[2]
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库来做了一些增加可读性的操作

from typing import Dict, List

CHAR_TO_OUTPUT: Dict[str, str] = {
    ">": "\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的内存空间

output: List[str] = []

output.append("#include <stdio.h>\n\n")
output.append("int main(void)\n")
output.append("{\n")
output.append("\tchar array[30000] = {0};\n")
output.append("\tchar *ptr = array;\n\n")

接下去,刚才已经定义好字典了,那我们只需简单的用循环来遍历bf的程序,并使用CHAR_TO_OUTPUT字典来获取对应的字符串,然后添加到output就好了

for c in program:
    if c in CHAR_TO_OUTPUT:
        output.append(CHAR_TO_OUTPUT[c])

最后,添加一些必要的结束语句,并将列表中的元素用换行符连接起来就好了

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)

示例

用一个简单的HelloWorld程序测试下

++++++++++[>+++++++>++++++++++>+++>+<<<<-]
>++.>+.+++++++..+++.>++.<<+++++++++++++++.
>.+++.------.--------.>+.>.

来到终端

PS [private]\BrainFuck> python main.py hello.bf hello.c
PS [private]\BrainFuck> gcc hello.c -o hello
PS [private]\BrainFuck> ./hello
Hello World!
PS [private]\BrainFuck>

测试成功!

完整代码

import sys
from typing import Dict, List

CHAR_TO_OUTPUT: Dict[str, str] = {
    ">": "\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[0]} 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[1]
try:
    output_file = sys.argv[2]
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[str] = []

output.append("#include <stdio.h>\n\n")
output.append("int main(void)\n")
output.append("{\n")
output.append("\tchar array[30000] = {0};\n")
output.append("\tchar *ptr = array;\n\n")

for c in program:
    if c in CHAR_TO_OUTPUT:
        output.append(CHAR_TO_OUTPUT[c])

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)

免费评分

参与人数 2吾爱币 +9 热心值 +2 收起 理由
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
Tonyha7 + 2 + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Sogrey 发表于 2023-9-27 23:55
亲测有效。最近在重学c++,这样的程序还挺新鲜的
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 20:13

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表