void encryptContent(unsigned char* addr, int len) {
if(len < 16) {
ALOGE("enctyptContent len=%d is too low", len);
return;
}
ALOGE("enctyptContent");
AES_KEY aes;
unsigned char ivec[17] = "AESmyencryptokey";
unsigned char key[17] = "myencryptokeyAES";
AES_set_encrypt_key(key, 128, &aes);
int Len = len/16;
int iLen = Len*16;
unsigned char* tmp = new unsigned char[iLen];
ALOGE("encrypt, byte[0x0]=%x byte[0x1]=%x byte[0x2]=%x byte[0x3]=%x byte[0x4]=%x byte[5]=%x byte[6]=%x byte[7]=%x",
addr[0x0], addr[0x1], addr[0x2], addr[0x3], addr[0x4], addr[0x5], addr[0x6], addr[0x7]);
AES_cbc_encrypt(addr, tmp, iLen, &aes, ivec, AES_ENCRYPT);
ALOGE("dst, byte[0x0]=%x byte[0x1]=%x byte[0x2]=%x byte[0x3]=%x byte[0x4]=%x byte[5]=%x byte[6]=%x byte[7]=%x",
tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6], tmp[7]);
memcpy(addr, tmp, iLen);
delete tmp;
}
int main(int argc, char *argv[]) {
ALOGE("argv[1]=%s", argv[1]);
name_ = argv[1];
int len = strlen(name_);
int offset = 0;
int i;
unsigned char* content;
if (strcasecmp(name_ + len -2, "so") == 0) {
fd_ = open(name_, O_RDWR);
if(fd_ < 0) {
goto _error;
}
if(read(fd_, &header_, sizeof(header_)) != sizeof(header_)) {
ALOGE("Read ELF header error");
goto _error;
}
if(header_.e_ident[EI_MAG0] != ELFMAG0) {
ALOGE("ELF header error mag0:%x", header_.e_ident[EI_MAG0]);
goto _error;
}
ALOGE("encrypt sections header");
shdr_num_ = header_.e_shnum;
unsigned char sections_head[shdr_num_*sizeof(Elf32_Shdr)];
lseek(fd_, header_.e_shoff, SEEK_SET);
if(read(fd_, sections_head, shdr_num_*sizeof(Elf32_Shdr)) != shdr_num_*sizeof(Elf32_Shdr)) {
ALOGE("Read sections header error");
goto _error;
}
encryptContent(sections_head, shdr_num_*sizeof(Elf32_Shdr));
lseek(fd_, header_.e_shoff, SEEK_SET);
write(fd_, sections_head, shdr_num_*sizeof(Elf32_Shdr));
ALOGE("encrypt PT_LOAD Segments");
phdr_num_ = header_.e_phnum;
lseek(fd_, header_.e_phoff, SEEK_SET);
for(i = phdr_num_-1; i >= 0; i--) {
lseek(fd_, header_.e_phoff+i*sizeof(Elf32_Phdr), SEEK_SET);
if(read(fd_, &phdr, sizeof(Elf32_Phdr)) != sizeof(Elf32_Phdr)) {
ALOGE("Read phdr header error");
goto _error;
}
ALOGE("phdr.p_type 0x%x, phdr.p_offset 0x%x, phdr.p_filesz 0x%x", phdr.p_type, phdr.p_offset, phdr.p_filesz);
if(phdr.p_type == PT_LOAD && phdr.p_filesz >= (16+sizeof(header_))) {
offset = phdr.p_offset;
len = phdr.p_filesz;
if(phdr.p_offset < (sizeof(header_)+phdr_num_*sizeof(Elf32_Phdr))) {
offset = sizeof(header_)+phdr_num_*sizeof(Elf32_Phdr);
len -= sizeof(header_)+phdr_num_*sizeof(Elf32_Phdr)-phdr.p_offset;
}
lseek(fd_, offset, SEEK_SET);
content = (unsigned char*) malloc(len);
if(read(fd_, content, len) != len) {
ALOGE("Read phdr content error");
goto _error;
}
encryptContent(content, len);
lseek(fd_, offset, SEEK_SET);
write(fd_, content, len);
free(content);
}
}
ALOGE("encrypt elf header");
encryptContent((unsigned char*)(&header_)+4, sizeof(header_)-4);
header_.e_ident[EI_MAG0] = 0xf7;
lseek(fd_, 0, SEEK_SET);
write(fd_, &header_, sizeof(header_));
}
_error:
if (fd_ >= 0)
close(fd_);
return 0;
}