mirror of
https://github.com/radareorg/radare2.git
synced 2025-02-13 18:32:56 +00:00
Add a way to compare claimed CRC (in header) of PE files with the actual CRC.
This commit is contained in:
parent
977aeb8173
commit
5c3f5904ea
@ -558,6 +558,61 @@ struct symrec {
|
||||
return true;
|
||||
}
|
||||
|
||||
int PE_(bin_pe_get_claimed_checksum)(struct PE_(r_bin_pe_obj_t) *bin) {
|
||||
return bin->nt_headers->optional_header.CheckSum;
|
||||
}
|
||||
|
||||
int PE_(bin_pe_get_actual_checksum)(struct PE_(r_bin_pe_obj_t) *bin) {
|
||||
int i, j;
|
||||
int checksum_offset = bin->nt_header_offset + 4 + sizeof(PE_(image_file_header)) + 0x40;
|
||||
|
||||
ut8 *buf = bin->b->buf;
|
||||
ut64 computed_cs = 0;
|
||||
int remaining_bytes;
|
||||
int shift;
|
||||
ut32 cur;
|
||||
for (i = 0; i < bin->size / 4; i++) {
|
||||
cur = (buf[i * 4] << 0) |
|
||||
(buf[i * 4 + 1] << 8) |
|
||||
(buf[i * 4 + 2] << 16) |
|
||||
(buf[i * 4 + 3] << 24);
|
||||
|
||||
// skip the checksum bytes
|
||||
if (i * 4 == checksum_offset) {
|
||||
continue;
|
||||
}
|
||||
|
||||
computed_cs = (computed_cs & 0xFFFFFFFF) + cur + (computed_cs >> 32);
|
||||
if (computed_cs >> 32) {
|
||||
computed_cs = (computed_cs & 0xFFFFFFFF) + (computed_cs >> 32);
|
||||
}
|
||||
}
|
||||
|
||||
// add resultant bytes to checksum
|
||||
remaining_bytes = bin->size % 4;
|
||||
i = i * 4;
|
||||
if (remaining_bytes != 0) {
|
||||
cur = buf[i];
|
||||
shift = 8;
|
||||
for (j = 1; j < remaining_bytes; j++, shift += 8) {
|
||||
cur |= buf[i + j] << shift;
|
||||
}
|
||||
computed_cs = (computed_cs & 0xFFFFFFFF) + cur + (computed_cs >> 32);
|
||||
if (computed_cs >> 32) {
|
||||
computed_cs = (computed_cs & 0xFFFFFFFF) + (computed_cs >> 32);
|
||||
}
|
||||
}
|
||||
|
||||
// 32bits -> 16bits
|
||||
computed_cs = (computed_cs & 0xFFFF) + (computed_cs >> 16);
|
||||
computed_cs = (computed_cs) + (computed_cs >> 16);
|
||||
computed_cs = (computed_cs & 0xFFFF);
|
||||
|
||||
// add filesize
|
||||
computed_cs += bin->size;
|
||||
return computed_cs;
|
||||
}
|
||||
|
||||
static int bin_pe_init_imports(struct PE_(r_bin_pe_obj_t) *bin) {
|
||||
PE_(image_data_directory) *data_dir_import = \
|
||||
&bin->nt_headers->optional_header.DataDirectory[ \
|
||||
|
@ -357,6 +357,8 @@ static int haschr(const RBinFile* arch, ut16 dllCharacteristic) {
|
||||
static RBinInfo* info(RBinFile *arch) {
|
||||
SDebugInfo di = {{0}};
|
||||
RBinInfo *ret = R_NEW0 (RBinInfo);
|
||||
ut32 claimed_checksum, actual_checksum;
|
||||
|
||||
if (!ret) return NULL;
|
||||
arch->file = strdup (arch->file);
|
||||
ret->bclass = PE_(r_bin_pe_get_class) (arch->o->bin_obj);
|
||||
@ -374,12 +376,18 @@ static RBinInfo* info(RBinFile *arch) {
|
||||
if (PE_(r_bin_pe_is_dll) (arch->o->bin_obj))
|
||||
ret->type = strdup ("DLL (Dynamic Link Library)");
|
||||
else ret->type = strdup ("EXEC (Executable file)");
|
||||
|
||||
claimed_checksum = PE_(bin_pe_get_claimed_checksum) (arch->o->bin_obj);
|
||||
actual_checksum = PE_(bin_pe_get_actual_checksum) (arch->o->bin_obj);
|
||||
|
||||
ret->bits = PE_(r_bin_pe_get_bits) (arch->o->bin_obj);
|
||||
ret->big_endian = PE_(r_bin_pe_is_big_endian) (arch->o->bin_obj);
|
||||
ret->dbg_info = 0;
|
||||
ret->has_canary = has_canary (arch);
|
||||
ret->has_nx = haschr (arch, IMAGE_DLL_CHARACTERISTICS_NX_COMPAT);
|
||||
ret->has_pi = haschr (arch, IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE);
|
||||
ret->claimed_checksum = strdup (sdb_fmt (0, "0x%08x", claimed_checksum));
|
||||
ret->actual_checksum = strdup (sdb_fmt (1, "0x%08x", actual_checksum));
|
||||
|
||||
sdb_bool_set (arch->sdb, "pe.canary", has_canary(arch), 0);
|
||||
sdb_bool_set (arch->sdb, "pe.highva", haschr(arch, IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA), 0);
|
||||
@ -394,8 +402,11 @@ static RBinInfo* info(RBinFile *arch) {
|
||||
sdb_bool_set (arch->sdb, "pe.guardcf", haschr(arch, IMAGE_DLLCHARACTERISTICS_GUARD_CF), 0);
|
||||
sdb_bool_set (arch->sdb, "pe.terminalserveraware", haschr(arch, IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE), 0);
|
||||
sdb_num_set (arch->sdb, "pe.bits", ret->bits, 0);
|
||||
sdb_set (arch->sdb, "pe.claimed_checksum", ret->claimed_checksum, 0);
|
||||
sdb_set (arch->sdb, "pe.actual_checksum", ret->actual_checksum, 0);
|
||||
|
||||
ret->has_va = true;
|
||||
|
||||
if (!PE_(r_bin_pe_is_stripped_debug) (arch->o->bin_obj))
|
||||
ret->dbg_info |= R_BIN_DBG_STRIPPED;
|
||||
if (PE_(r_bin_pe_is_stripped_line_nums) (arch->o->bin_obj))
|
||||
|
@ -507,6 +507,12 @@ static int bin_info(RCore *r, int mode) {
|
||||
pair_str ("guid", info->guid, mode, false);
|
||||
pair_str ("dbg_file", info->debug_file_name, mode, true);
|
||||
|
||||
// checksums are only supported for pe atm
|
||||
if (strncmp ("pe", info->rclass, 2) == 0) {
|
||||
pair_str ("crc32", info->claimed_checksum, mode, false);
|
||||
pair_str ("crc32c", info->actual_checksum, mode, false);
|
||||
}
|
||||
|
||||
for (i = 0; info->sum[i].type; i++) {
|
||||
int len;
|
||||
|
||||
|
@ -111,6 +111,8 @@ typedef struct r_bin_info_t {
|
||||
int has_crypto;
|
||||
int has_nx;
|
||||
int big_endian;
|
||||
char *actual_checksum;
|
||||
char *claimed_checksum;
|
||||
ut64 dbg_info;
|
||||
RBinHash sum[3];
|
||||
ut64 baddr;
|
||||
|
Loading…
x
Reference in New Issue
Block a user