1.加密
直接复制李明华的代码
http://www.xuanyusong.com/archives/3571
修改char target_section[] = “.mytext”;为自己image.c里解密dll函数的section名
encrypt_section.c
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
/* 32-bit ELF base types. */
typedef unsigned int Elf32_Addr;
typedef unsigned short Elf32_Half;
typedef unsigned int Elf32_Off;
typedef signed int Elf32_Sword;
typedef unsigned int Elf32_Word;
#define EI_NIDENT 16
/*
* ELF header.
*/
typedef struct {
unsigned char e_ident[EI_NIDENT]; /* File identification. */
Elf32_Half e_type; /* File type. */
Elf32_Half e_machine; /* Machine architecture. */
Elf32_Word e_version; /* ELF format version. */
Elf32_Addr e_entry; /* Entry point. */
Elf32_Off e_phoff; /* Program header file offset. */
Elf32_Off e_shoff; /* Section header file offset. */
Elf32_Word e_flags; /* Architecture-specific flags. */
Elf32_Half e_ehsize; /* Size of ELF header in bytes. */
Elf32_Half e_phentsize; /* Size of program header entry. */
Elf32_Half e_phnum; /* Number of program header entries. */
Elf32_Half e_shentsize; /* Size of section header entry. */
Elf32_Half e_shnum; /* Number of section header entries. */
Elf32_Half e_shstrndx; /* Section name strings section. */
} Elf32_Ehdr;
/*
* Section header.
*/
typedef struct {
Elf32_Word sh_name; /* Section name (index into the
section header string table). */
Elf32_Word sh_type; /* Section type. */
Elf32_Word sh_flags; /* Section flags. */
Elf32_Addr sh_addr; /* Address in memory image. */
Elf32_Off sh_offset; /* Offset in file. */
Elf32_Word sh_size; /* Size in bytes. */
Elf32_Word sh_link; /* Index of a related section. */
Elf32_Word sh_info; /* Depends on section type. */
Elf32_Word sh_addralign; /* Alignment in bytes. */
Elf32_Word sh_entsize; /* Size of each entry in section. */
} Elf32_Shdr;
int main(int argc, char** argv){
char target_section[] = ".mytext";
char *shstr = NULL;
char *content = NULL;
Elf32_Ehdr ehdr;
Elf32_Shdr shdr;
int i;
unsigned int base, length;
unsigned short nblock;
unsigned short nsize;
unsigned char block_size = 16;
int fd;
if(argc < 2){
puts("Input .so file");
return -1;
}
fd = open(argv[1], O_RDWR);
if(fd < 0){
printf("open %s failed\n", argv[1]);
goto _error;
}
if(read(fd, &ehdr, sizeof(Elf32_Ehdr)) != sizeof(Elf32_Ehdr)){
puts("Read ELF header error");
goto _error;
}
lseek(fd, ehdr.e_shoff + sizeof(Elf32_Shdr) * ehdr.e_shstrndx, SEEK_SET);
if(read(fd, &shdr, sizeof(Elf32_Shdr)) != sizeof(Elf32_Shdr)){
puts("Read ELF section string table error");
goto _error;
}
if((shstr = (char *) malloc(shdr.sh_size)) == NULL){
puts("Malloc space for section string table failed");
goto _error;
}
lseek(fd, shdr.sh_offset, SEEK_SET);
if(read(fd, shstr, shdr.sh_size) != shdr.sh_size){
puts("Read string table failed");
goto _error;
}
lseek(fd, ehdr.e_shoff, SEEK_SET);
for(i = 0; i < ehdr.e_shnum; i++){
if(read(fd, &shdr, sizeof(Elf32_Shdr)) != sizeof(Elf32_Shdr)){
puts("Find section .text procedure failed");
goto _error;
}
if(strcmp(shstr + shdr.sh_name, target_section) == 0){
base = shdr.sh_offset;
length = shdr.sh_size;
printf("Find section %s\n", target_section);
break;
}
}
lseek(fd, base, SEEK_SET);
content = (char*) malloc(length);
if(content == NULL){
puts("Malloc space for content failed");
goto _error;
}
if(read(fd, content, length) != length){
puts("Read section .text failed");
goto _error;
}
nblock = length / block_size;
nsize = base / 4096 + (base % 4096 == 0 ? 0 : 1);
printf("base = %d, length = %d\n", base, length);
printf("nblock = %d, nsize = %d\n", nblock, nsize);
ehdr.e_entry = (length << 16) + nsize;
ehdr.e_shoff = base;
for(i=0;i<length;i++){
content[i] = ~content[i];
}
lseek(fd, 0, SEEK_SET);
if(write(fd, &ehdr, sizeof(Elf32_Ehdr)) != sizeof(Elf32_Ehdr)){
puts("Write ELFhead to .so failed");
goto _error;
}
lseek(fd, base, SEEK_SET);
if(write(fd, content, length) != length){
puts("Write modified content to .so failed");
goto _error;
}
puts("Completed");
_error:
free(content);
free(shstr);
close(fd);
return 0;
}
系统环境iMac
gcc编译,输入命令:gcc -o encry encrypt_section.c
生成encry的执行文件,输入命令:./encry libmono.so
新生成的libmono.so就是加密之后的文件,可以直接拷贝到Unity安装目录下(windows版)\Editor\Data\PlaybackEngines\androidplayer\release\libs\armeabi-v7a
使用unity导出新项目时就可自动替换。
mono解密dll代码段
还是直接使用李明华的代码
http://www.xuanyusong.com/archives/3571
//SO---------------加密----------------------
#include <sys/types.h>
#include <elf.h>
#include <sys/mman.h>
//注意上面说解密算法里面的断.mytext就是这里,
//这里把getKey进行了加密,这样对方拿不到你的密钥都没法破解你的dll了
int getKey() __attribute__((section (".mytext")));
int getKey(){
return 2048;
};
//这里就是.so初始化的时候,这里进行mytext断的解密工作
void init_getKey() __attribute__((constructor));
unsigned long getLibAddr();
void init_getKey(){
char name[15];
unsigned int nblock;
unsigned int nsize;
unsigned long base;
unsigned long text_addr;
unsigned int i;
Elf32_Ehdr *ehdr;
Elf32_Shdr *shdr;
base = getLibAddr();
ehdr = (Elf32_Ehdr *)base;
text_addr = ehdr->e_shoff + base;
nblock = ehdr->e_entry >> 16;
nsize = ehdr->e_entry & 0xffff;
g_message("momo: nblock = %d\n", nblock);
if(mprotect((void *) base, 4096 * nsize, PROT_READ | PROT_EXEC | PROT_WRITE) != 0){
g_message("momo: mem privilege change failed");
}
//注意这里就是解密算法, 要和加密算法完全逆向才行不然就解不开了。
for(i=0;i< nblock; i++){
char *addr = (char*)(text_addr + i);
*addr = ~(*addr);
}
if(mprotect((void *) base, 4096 * nsize, PROT_READ | PROT_EXEC) != 0){
g_message("momo: mem privilege change failed");
}
g_message("momo: Decrypt success");
}
unsigned long getLibAddr(){
unsigned long ret = 0;
char name[] = "libmono.so";
char buf[4096], *temp;
int pid;
FILE *fp;
pid = getpid();
sprintf(buf, "/proc/%d/maps", pid);
fp = fopen(buf, "r");
if(fp == NULL)
{
g_message("momo: open failed");
goto _error;
}
while(fgets(buf, sizeof(buf), fp)){
if(strstr(buf, name)){
temp = strtok(buf, "-");
ret = strtoul(temp, NULL, 16);
break;
}
}
_error:
fclose(fp);
return ret;
}
//SO---------------加密----------------------
这个必须放在image.c的最前面,因为这个init_getKey函数没有查找mytext段,直接取的第一个section。
看了下李明华文章下面的评论,使用hook mono_image_open_from_data_with_name还是能够提取出dll的,因为到了内存里dll就是解密好的原始文件。
参考:
http://www.xuanyusong.com/archives/3571
http://bbs.pediy.com/showthread.php?t=191649
http://0nly3nd.sinaapp.com/?p=695
http://blog.163.com/lhmood@126/blog/static/236614472009112693539253/
http://jzhihui.iteye.com/blog/1447570
ida pro
http://pan.baidu.com/s/1gd3lXtD
http://www.h4ck.org.cn/2014/08/ida-pro-6-5-with-hex-rays-x86-decompiler-v1-5-and-hex-rays-arm-decompiler-1-7/