aes-finder
aes-finder copied to clipboard
Need some help
I am writing my own aes keys finding code in c language for jni android project, key finding works fine but problem is 'little endian', my code able to find only big endian keys
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/uio.h>
#include <time.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <stdbool.h>
#include "table.h" // aes table
#ifndef process_vm_readv
#include <sys/syscall.h>
#include <asm/unistd.h>
ssize_t process_vm_readv(pid_t pid, const struct iovec *local_iov, unsigned long liovcnt, const struct iovec *remote_iov, unsigned long riovcnt, unsigned long flags) {
return syscall(__NR_process_vm_readv, pid, local_iov, liovcnt, remote_iov, riovcnt, flags);
}
#endif
ssize_t read_process_memory(pid_t pid, uintptr_t address, void *value, size_t size) {
struct iovec local[1];
struct iovec remote[1];
local[0].iov_base = value;
local[0].iov_len = size;
remote[0].iov_base = (void*)address;
remote[0].iov_len = size;
return process_vm_readv(pid, local, 1, remote, 1, 0);
}
pid_t find_pid(const char *process_name) {
DIR *dir = opendir("/proc");
struct dirent *entry = NULL;
char cmdline_path[256];
char cmdline[256];
int fd;
if (dir == NULL) {
return -1;
}
while ((entry = readdir(dir)) != NULL) {
if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0) || (entry->d_type != DT_DIR) || (strspn(entry->d_name, "0123456789") != strlen(entry->d_name))) {
continue;
}
snprintf(cmdline_path, sizeof(cmdline_path), "/proc/%s/cmdline", entry->d_name);
fd = open(cmdline_path, O_RDONLY);
read(fd, cmdline, 256);
close(fd);
if (strstr(cmdline, process_name) != NULL) {
closedir(dir);
return atoi(entry->d_name);
}
}
closedir(dir);
return -1;
}
uint8_t get_module_address(pid_t process_id, const char *module_name, uint64_t *start_addr, uint64_t *end_addr) {
char filename[256];
char line[1024];
FILE *fp = NULL;
uint8_t address_found = 0;
uint64_t start, end;
uint8_t permission;
snprintf(filename, sizeof(filename), "/proc/%d/maps", process_id);
if (!(fp = fopen(filename, "r"))) {
return 0;
}
while (fgets(line, sizeof(line), fp)) {
if (strstr(line, module_name)) {
if (sscanf(line, "%lx-%lx %c", &start, &end, &permission) == 3) {
if (permission != 'r') {
continue;
}
address_found = 1;
*start_addr = start;
*end_addr = end;
break;
}
}
}
fclose(fp);
return address_found;
}
// Detection aes 128 encryption key
bool aes128_detect_enc(const unsigned int *data) {
unsigned int roundkey[44];
roundkey[0] = data[0];
roundkey[1] = data[1];
roundkey[2] = data[2];
roundkey[3] = data[3];
for (unsigned char index = 4; index < 44; index += 4) {
roundkey[index] = roundkey[index - 4] ^
(Te4[(roundkey[index - 1] >> 16) & 0xff] & 0xff000000) ^
(Te4[(roundkey[index - 1] >> 8) & 0xff] & 0x00ff0000) ^
(Te4[(roundkey[index - 1] >> 0) & 0xff] & 0x0000ff00) ^
(Te4[(roundkey[index - 1] >> 24) & 0xff] & 0x000000ff) ^ rcon[index / 4 - 1];
roundkey[index + 1] = roundkey[index - 3] ^ roundkey[index];
roundkey[index + 2] = roundkey[index - 2] ^ roundkey[index + 1];
roundkey[index + 3] = roundkey[index - 1] ^ roundkey[index + 2];
}
for (int index = 0; index < 44; index++) {
if (roundkey[index] != data[index]) {
return false;
}
}
return true;
}
bool aes128_detect_dec(const unsigned int *data) {
unsigned int roundkey[44];
roundkey[0] = data[40];
roundkey[1] = data[41];
roundkey[2] = data[42];
roundkey[3] = data[43];
for (unsigned char index = 4; index < 44; index += 4) {
roundkey[index] = roundkey[index - 4] ^
(Te4[(roundkey[index - 1] >> 16) & 0xff] & 0xff000000) ^
(Te4[(roundkey[index - 1] >> 8) & 0xff] & 0x00ff0000) ^
(Te4[(roundkey[index - 1] >> 0) & 0xff] & 0x0000ff00) ^
(Te4[(roundkey[index - 1] >> 24) & 0xff] & 0x000000ff) ^ rcon[index / 4 - 1];
roundkey[index + 1] = roundkey[index - 3] ^ roundkey[index];
roundkey[index + 2] = roundkey[index - 2] ^ roundkey[index + 1];
roundkey[index + 3] = roundkey[index - 1] ^ roundkey[index + 2];
}
unsigned int temp;
// Next, invert the order of the round keys.
for (unsigned char i = 0, j = 40; i < j; i += 4, j -= 4) {
for (uint8_t k = 0; k < 4; k++) {
temp = roundkey[i + k];
roundkey[i + k] = roundkey[j + k];
roundkey[j + k] = temp;
}
}
// Finally, apply the inverse MixColumn transform to all round keys except the first and last.
for (unsigned char index = 4; index < 40; index += 4) {
roundkey[index] =
Td0[Te4[(roundkey[index] >> 24) & 0xff] & 0xff] ^
Td1[Te4[(roundkey[index] >> 16) & 0xff] & 0xff] ^
Td2[Te4[(roundkey[index] >> 8) & 0xff] & 0xff] ^
Td3[Te4[(roundkey[index] >> 0) & 0xff] & 0xff];
roundkey[index + 1] =
Td0[Te4[(roundkey[index + 1] >> 24) & 0xff] & 0xff] ^
Td1[Te4[(roundkey[index + 1] >> 16) & 0xff] & 0xff] ^
Td2[Te4[(roundkey[index + 1] >> 8) & 0xff] & 0xff] ^
Td3[Te4[(roundkey[index + 1] >> 0) & 0xff] & 0xff];
roundkey[index + 2] =
Td0[Te4[(roundkey[index + 2] >> 24) & 0xff] & 0xff] ^
Td1[Te4[(roundkey[index + 2] >> 16) & 0xff] & 0xff] ^
Td2[Te4[(roundkey[index + 2] >> 8) & 0xff] & 0xff] ^
Td3[Te4[(roundkey[index + 2] >> 0) & 0xff] & 0xff];
roundkey[index + 3] =
Td0[Te4[(roundkey[index + 3] >> 24) & 0xff] & 0xff] ^
Td1[Te4[(roundkey[index + 3] >> 16) & 0xff] & 0xff] ^
Td2[Te4[(roundkey[index + 3] >> 8) & 0xff] & 0xff] ^
Td3[Te4[(roundkey[index + 3] >> 0) & 0xff] & 0xff];
}
for (int x = 0; x < 44; x++) {
if (roundkey[x] != data[x]) {
return false;
}
}
return true;
}
void find_keys(const unsigned long long address, const uint8_t *buffer) {
uint32_t *data = (uint32_t*)buffer;
if (aes128_detect_enc(data)) {
printf("[%p] Found AES-128 encryption key: 0x", (void*)address);
for (int index = 0; index < 4; index++) {
printf("%X", data[index]);
}
printf("\n");
} else if (aes128_detect_dec(data)) {
printf("[%p] Found AES-128 decryption key: 0x", (void*)address);
for (int index = 40; index < 44; index++) {
printf("%X", data[index]);
}
printf("\n");
}
}
int main(int argc, const char *argv[]) {
const char* package = argv[1]; // target program or application
const char* module = "[stack]"; // target module
uint64_t start = 0, end = 0;
uint8_t data[240];
pid_t pid = -1;
printf("[INFO] Waiting for opening '%s' process\n", package);
while (pid == -1) {
pid = find_pid(package);
}
printf("[INFO] Process '%s' is now open pid %d\n", package, pid);
printf("[INFO] Searching keys...\n");
if (!get_module_address(pid, module, &start, &end)) {
printf("[ERROR] Can't find module address\n");
return 1;
}
uint64_t address = start;
uint64_t remaining = end - start;
while (remaining > 0) {
if (read_process_memory(pid, address, data, 240) == -1) {
printf("[ERROR] Can't read memory at %p\n", (void*)&start);
break;
}
find_keys(address, data);
remaining--;
address++;
}
return 0;
}