使用二进制代码和密钥防止逆向工程 [英] Preventing reverse engineering with binary code and secret key

查看:63
本文介绍了使用二进制代码和密钥防止逆向工程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个软件程序,该程序必须部署在具有 root 访问权限的客户端的私有云服务器上.我可以通过安全端口与软件通信.

我想阻止客户对我的程序进行逆向工程,或者至少让它足够难".以下是我的方法:

  1. 用Go编写代码,将软件编译成二进制代码(可能有混淆)
  2. 确保程序只能使用可以通过安全端口发送的密钥启动.密钥可能会随时间变化.
  3. 每次我需要启动/停止程序时,我都可以通过安全端口发送带有密钥的命令.

我认为这种方法可以防止 root 用户:

  1. 使用调试器对我的代码进行逆向工程

  2. 反复运行程序检查输出

我的问题是:这个设计的弱点是什么?root 用户如何攻击它?

解决方案

我想阻止客户对我的程序进行逆向工程,

当软件在不属于您的硬件上运行时,您无法完全防止这种情况发生.要运行该软件,CPU 必须查看程序的所有指令,并将它们存储在计算机内存中.

https://softwareengineering.stackexchange.com/questions/46434/how-can-software-be-protected-from-piracy

<块引用>

代码就是数据.当代码可运行时,该数据的副本是不受保护的代码.可以复制未受保护的代码.

使用反盗版检查对代码进行强化会使其稍微困难一些,但黑客只会使用调试器将其删除.插入空操作而不是调用check_license"非常简单.

(https://softwareengineering.stackexchange.com/questions/46434 中的答案可能对您有用)

硬件所有者控制操作系统和内存,他可以转储所有内容.

<块引用>

或者至少让它足够难".

你只能让它更难一点.

<块引用>

用Go编写代码,将软件编译成二进制代码(可能有混淆)

IDA 将反编译任何机器代码.使用原生机器码比字节码(java 或 .NET 或 dex)强一点

<块引用>

确保程序只能使用可以通过安全端口发送的密钥启动.密钥可能会随时间变化.

如果相同密钥(密钥)的副本在程序的代码或内存中,用户可以转储它并模拟您的服务器.如果您的代码的一部分或代码运行所需的部分数据被加密存储,并使用此类外部密钥解密,则用户可能会窃听密钥(在它从 SSL 解码之后但在它用于解密秘密部分之前)代码),或从内存中转储解密的代码/数据(即使使用默认的预装工具,如 Linux 中的 strace,也很容易看到在内存中创建的新可执行代码,只需搜索所有 mmapsPROT_EXEC 标志)

<块引用>

每次我需要启动/停止程序时,我都可以通过安全端口发送带有密钥的命令.

这只是在线许可/反盗版检查的一种变体(电话回家")

<块引用>

我认为这种方法可以防止 root 用户:使用调试器对我的代码进行逆向工程,或者

不,他可以随时启动调试器;但是,如果程序经常(每 5 秒)与您的服务器通信,那么您可以使使用交互式调试器变得更加困难.但是如果它经常通信,最好将部分计算移到你的服务器上;这部分将受到保护.

而且他仍然可以使用非交互式调试器、跟踪工具和内存转储.他也可以在虚拟机中运行程序,等到在线检查完成(使用 tcpdump 和 netstat 监控网络流量),然后做虚拟机的实时快照(有几个变体可以启用虚拟机的实时迁移";只有短暂的停顿如果有外部定时,可能会被你的程序记录下来),继续在线运行第一个副本,并拍摄快照以进行离线调试(其中包含所有密钥和解密代码).

<块引用>

反复运行程序检查输出

直到他破解通讯...

I am working on a software program that has to be deployed on private cloud server of a client, who has root access. I can communicate with the software through a secure port.

I want to prevent client from reverse engineering my program, or at least make it "hard enough". Below is my approach:

  1. Write code in Go and compile the software into binary code (may be with obfuscation)
  2. Make sure that program can only be initiated with secret key that can be sent through the secure port. The secret key can be changing depending on time.
  3. Every time I need to start/stop the program, I can send commands with the secret keys through the secured port.

I think this approach can prevent a root user from either:

  1. Using a debugger to reverse engineer my code

  2. Running the program repeatedly to check outputs

My question is: What are the weak spots of this design? How can a root user attack it?

解决方案

I want to prevent client from reverse engineering my program,

You can't prevent this fully when software runs on hardware you don't own. To run the software, the CPU must see all instructions of the program, and they will be stored in the computer memory.

https://softwareengineering.stackexchange.com/questions/46434/how-can-software-be-protected-from-piracy

Code is data. When the code is runnable, a copy of that data is un-protected code. Unprotected code can be copied.

Peppering the code with anti-piracy checks makes it slightly harder, but hackers will just use a debugger and remove them. Inserting no-ops instead of calls to "check_license" is pretty easy.

(answers in https://softwareengineering.stackexchange.com/questions/46434 may be useful for you)

Hardware owner controls the OS and memory, he can dump everything.

or at least make it "hard enough".

You can only make it a bit harder.

Write code in Go and compile the software into binary code (may be with obfuscation)

IDA will decompile any machine code. Using native machine code is a bit stronger than bytecode (java or .NET or dex)

Make sure that program can only be initiate with secret key that can be sent through the secure port. The secret key can be changing depending on time.

If the copy of the same secret key (keys) is in code or memory of the program, user may dump it and simulate your server. If part of your code, or part of data needed for code to run is stored encrypted, and deciphered with such external key, user may either eavesdrop the key (after it will be decoded from SSL but before it will be used to decrypt secret part of code), or dump decrypted code/data from the memory (It is very easy to see new executable code created in memory even with default preinstalled tools like strace in Linux, just search for all mmaps with PROT_EXEC flags)

Every time I need to start/stop the program, I can send commands with the secret keys through the secured port.

This is just a variation of online license/antipiracy check ("phone home")

I think this approach can prevent a root user to: use a debugger to reverse engineer my code, or

No, he can start debugger at any time; but you can make it a bit harder to use interactive debugger, if the program communicates with your server often (every 5 seconds). But if it communicates so often it is better to move some part of computations to your server; this part will be protected.

And he still can use non-interactive debuggers, tracing tools and memory dumping. Also he can run program in virtual machine, wait until online check is done (using tcpdump and netstat to monitor network traffic), then do live snapshot of the VM (there are several variants to enable "live migration" of VM; only short pause may be recorded by your program if it has external timing), continue to run the first copy online, and take snapshot for offline debugging (with all keys and decrypted code in it).

run the program repeatedly to check outputs

Until he cracks the communications...

这篇关于使用二进制代码和密钥防止逆向工程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆