Vector35 / Vector35/binaryninja-api

Improve support for 64 bit values in 32 bit binaries

Open
#4,157 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Component: Core Effort: Medium Impact: Medium
Dominant language
C++
Stars
1.3k
Forks
298
Avg merge
5d 5h
Merged PRs (30d)
19

Description

Currently in order to get best decompiler output, I need to define 2 32 bit variables in the example below. It uses crc64 and some kind of key scheduling algorithm that uses 64 bit values.

08048f42  uint32_t hash_part1
08048f42  uint32_t hash_part2
08048f42  hash_part1, hash_part2 = crc64(0, 0, key, strlen(key))
...
key_schedule(hash_part1, hash_part2, 16, state)
....

crc64 and key_schedule prototypes are like these:

uint64_t crc64(uint32_t hash1, uint32_t hash2, char* data, uint64_t size)
void key_schedule(uint32_t hash_part1, uint32_t hash_part2, int32_t fixed16, uint32_t* state)

For example there is a bit shifting in key_schedule that uses these two hash value:

int32_t hash_part1_ = hash_part1
hash_part1_ = hash_part1_ u>> 1 | hash_part2 << 31

Which could be simple writed like hash >>= 1.

When I try to set crc64 and key_schedule prototypes into these:

uint64_t crc64(uint64_t hash, char* data, uint64_t size)
void key_schedule(uint64_t hash, int32_t fixed16, uint32_t* state)f

It still returns two values from crc64 and calls key_schedule like this:

hash_part1, hash_part2 = crc64(0, key, strlen(key))
key_schedule(hash.d, 16, state)

And bit shifting look like this:

int32_t eax_1 = hash:4.d
int32_t hash_part1_ = hash.d
hash_part1_ = hash_part1_ u>> 1 | eax_1 << 31

Another example in same binary that does bit counting if ((0 | (value.d & 1)) != 0) { is very interesting:

08049701                uint64_t value
08049701                value.d = ptrace(PTRACE_PEEKDATA, parent_pid, regs.ebx, nullptr)
08049725                value:4.d = ptrace(PTRACE_PEEKDATA, parent_pid, regs.ebx + 4, nullptr)
08049727                int32_t counter = 0
080497aa                while ((value.d | value:4.d) != 0) {
08049750                  if ((0 | (value.d & 1)) != 0) {
08049779                    counter = 0(0xb82d3c24, counter, value:4.d)
08049758                  }
08049782                  int32_t edx_7 = value:4.d
0804978e                  value.d = value.d u>> 1 | edx_7 << 0x1f
08049794                  value:4.d = edx_7 u>> 1
0804978c                }

Which could be optimized into this:

08049701                uint64_t value
08049701                value.d = ptrace(PTRACE_PEEKDATA, parent_pid, regs.ebx, nullptr)
08049725                value:4.d = ptrace(PTRACE_PEEKDATA, parent_pid, regs.ebx + 4, nullptr)
08049727                int32_t counter = 0
080497aa                while (value) { // or  value != 0
08049750                  if ((value & 1) != 0) {
08049779                    counter = 0(0xb82d3c24, counter, value:4.d)
08049758                  }
08049782                  value  >>= 1 // or value  = value >> 1
0804978c                }

I think that there is a great opportunity for improving these outputs. Which would make output way more understandable and shorter.

Binary:
break.zip

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by examining the attached break.zip binary and the crc64, key_schedule, and 64-bit bit-counting examples described in the issue. Compare the current decompiler output with the requested 64-bit expressions; done means these cases produce concise, semantically equivalent 64-bit operations without manually split variables.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
compilers, reverse-engineering
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.