Skip to content
This repository has been archived by the owner on Dec 4, 2024. It is now read-only.

Commit

Permalink
commit
Browse files Browse the repository at this point in the history
  • Loading branch information
4ra1n committed Sep 9, 2023
0 parents commit 6ed271c
Show file tree
Hide file tree
Showing 38 changed files with 1,648 additions and 0 deletions.
44 changes: 44 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/

### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr

### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/

### VS Code ###
.vscode/

### Mac OS ###
.DS_Store

### Others ###
.idea/
cmake-build-debug/
cmake-build-release/
*.exe
65 changes: 65 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# code-encryptor-plus

## 介绍

使用`JNI`加密字节码,通过`JVMTI`解密字节码以保护代码

提供两份`DLL`文件,一份加密一份解密,实际运行只需使用解密`DLL`文件

加密和解密的过程可以指定具体的包名,只加密核心关键部分

详细文章参考:[JVMTI 加密字节码详解](http://127.0.0.1:8080)

加密后的`Class`文件变成无法解析的畸形文件

![jd-gui](img/002.png)

除了开头保持了`Magic`部分,后续是无法解析的字节

![hex](img/003.png)

## 快速开始

加密解密部分使用`C`做一层加密,使用`汇编`二层加密,已提供编译好的`Release`版本`DLL`文件嵌入`Jar`包中

仅支持`Windows 64位`/`JDK-8`环境,其他版本的`JDK`只需要更换`JNI.h`头文件重新编译,其他操作系统可能需要重写

加密你的`Jar`包:(指定`Jar`包和`package`加密包名)

```shell
java -jar code-encryptor-plus.jar patch --jar your-jar.jar --package com.your.pack
```

导出解密`DLL`文件:(默认导出到`code-encryptor-plus-temp`目录)

```shell
java -jar code-encryptor-plus.jar export
```

使用解密`DLL`启动`Jar`包:(使用`-agentlib`参数)

```shell
java -agentlib:D:\abs-path\decrypter=PACKAGE_NAME=com.your.pack --jar your-jar.jar
```

另外支持了简易的`GUI`版本,选择需要加密的`Jar`文件即可一键加密

![screenshot](img/001.png)

## 其他

不适用于`SpringBoot`场景,存在两个问题:
- `SpringBoot`不允许压缩`lib`依赖(这个有解决办法)
- `SpringBoot`启动扫描会分析`class`由于加密报错

网上提供了两种办法,可以参考

参考:https://zhuanlan.zhihu.com/p/545268749

类似地,启动扫描`class`的代码是无法使用这种加密的

## 致谢

感谢以下项目或文章提供的思路:
- https://juejin.cn/post/6844903487784894477
- https://github.com/sea-boat/ByteCodeEncrypt
Binary file added img/001.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/002.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/003.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
98 changes: 98 additions & 0 deletions native/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
cmake_minimum_required(VERSION 3.25)

################ JNI CONFIG START ################

project(native C)

set(CMAKE_C_STANDARD 11)

# INCLUDE JNI

find_package(JNI REQUIRED)

include_directories(${JNI_INCLUDE_DIRS})

################ JNI CONFIG END ##################

enable_language(ASM_MASM)

add_custom_target(
native_encrypt_asm ALL
COMMAND ml64 /c /Fo${CMAKE_CURRENT_BINARY_DIR}/native_encrypt_asm.obj
${CMAKE_CURRENT_SOURCE_DIR}/encrypt.asm
BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/native_encrypt_asm.obj
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)

add_custom_target(
native_decrypt_asm ALL
COMMAND ml64 /c /Fo${CMAKE_CURRENT_BINARY_DIR}/native_decrypt_asm.obj
${CMAKE_CURRENT_SOURCE_DIR}/decrypt.asm
BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/native_decrypt_asm.obj
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)

add_library(
encryptor SHARED
core_en.h
encryptor.h
encryptor.c

xxtea_common.c
xxtea_common.h
xxtea_en.h
xxtea_de.h
xxtea.c
)

add_library(
decrypter SHARED
core_de.h
start.c

xxtea_common.c
xxtea_common.h
xxtea_en.h
xxtea_de.h
xxtea.c
)

set_property(TARGET native_encrypt_asm PROPERTY
MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>"
)

set_property(TARGET native_decrypt_asm PROPERTY
MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>"
)

add_dependencies(encryptor native_encrypt_asm)

add_dependencies(decrypter native_decrypt_asm)

target_link_libraries(encryptor
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/native_encrypt_asm.obj
)

target_link_libraries(decrypter
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/native_decrypt_asm.obj
)

add_executable(
xxtea_test
xxtea_common.h
xxtea_common.c
xxtea_en.h
xxtea_de.h
xxtea.c
xxtea_test.c
)

add_executable(
decrypt_test
core_de.h
decrypt_test.c
)

target_link_libraries(decrypt_test
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/native_decrypt_asm.obj
)
9 changes: 9 additions & 0 deletions native/core_de.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef NATIVE_CORE_DE_H
#define NATIVE_CORE_DE_H

#endif //NATIVE_CORE_DE_H

#define LOG(msg) printf("[JVMTI-LOG] %s\n", msg)

// SEE decrypt.asm
extern void decrypt(unsigned char *, long);
9 changes: 9 additions & 0 deletions native/core_en.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef NATIVE_CORE_EN_H
#define NATIVE_CORE_EN_H

#endif //NATIVE_CORE_EN_H

#define LOG(msg) printf("[ENCRYPT] %s\n", msg)

// SEE encrypt.asm
extern void encrypt(unsigned char *, long);
62 changes: 62 additions & 0 deletions native/decrypt.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
.code
; FUNCTION decrypt
decrypt PROC
; init
push rbp
mov rbp, rsp
; save
push rbx
push rsi
push rdi
; char* str
mov rdi, rcx
; long length
mov rcx, rdx
; rbx = 0
xor rbx, rbx
; rbx = rbx + 4
add rbx, 004h
; signature
mov rsi, rcx
sub rsi, 001h
mov al, byte ptr [rdi+rsi]
mov ah, byte ptr [rdi+004h]
mov byte ptr [rdi+004h], al
mov byte ptr [rdi+rsi], ah
; reset
xor ah, ah
xor al, al
xor rsi, rsi
link_start:
; if ebx >= ecx goto end
cmp rbx, rcx
jge magic
; al = str[rdi+rbx]
mov al, byte ptr [rdi+rbx]
; al = al ^ 22
xor al, 022h
; al = al -1
sub al, 001h
; al = ~al
not al
; al = al ^ 11h
xor al, 011h
; al = al + 2
add al, 002h
; str[rdi+rbx] = al
mov byte ptr [rdi+rbx], al
; ebx ++
inc ebx
; loop
jmp link_start
magic:
; recover
pop rdi
pop rsi
pop rbx
; recover rbp
pop rbp
ret
decrypt ENDP

end
19 changes: 19 additions & 0 deletions native/decrypt_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "core_de.h"
#include "stdio.h"

void printHex(const unsigned char *arr, int length) {
for (int i = 0; i < length; i++) {
printf("%02X", arr[i]);
}
printf("\n");
}

int main() {
unsigned char code[12] = {
0xca, 0xfe, 0xba, 0xbe,
0x00, 0x00, 0x00, 0x05,
0x01, 0x02, 0x03, 0x04,
};
decrypt(code,12);
printHex(code,12);
}
69 changes: 69 additions & 0 deletions native/encrypt.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
.code
; FUNCTION encrypt
encrypt PROC
; init
push rbp
mov rbp, rsp
; save
push rbx
push rsi
push rdi
; char* str
mov rdi, rcx
; long length
mov rcx, rdx
; rbx = 0
xor rbx, rbx
link_start:
; if rbx >= rcx goto end
cmp rbx, rcx
jge magic
; al = str[rdi+rbx]
mov al, byte ptr [rdi+rbx]
; al = al - 2
sub al, 002h
; al = al ^ 11h
xor al, 011h
; al = ~al
not al
; al = al + 1
add al, 001h
; al = al ^ 22
xor al, 022h
; str[rdi+rbx] = al
mov byte ptr [rdi+rbx], al
; ebx ++
inc rbx
; loop
jmp link_start
magic:
; magic
mov al, 0CAh
mov byte ptr [rdi+000h], al
mov al, 0FEh
mov byte ptr [rdi+001h], al
mov al, 0BAh
mov byte ptr [rdi+002h], al
mov al, 0BEh
mov byte ptr [rdi+003h], al
; signature
mov rsi, rcx
sub rsi, 001h
mov al, byte ptr [rdi+rsi]
mov ah, byte ptr [rdi+004h]
mov byte ptr [rdi+004h], al
mov byte ptr [rdi+rsi], ah
; reset
xor ah, ah
xor al, al
xor rsi, rsi
; recover
pop rdi
pop rsi
pop rbx
; recover rbp
pop rbp
ret
encrypt ENDP

end
Loading

0 comments on commit 6ed271c

Please sign in to comment.