Reversing a complex boolean function

147 Views Asked by At

I am trying to reverse-engineer the DRAM address function of a memory controller. This is a function that maps a physical address to a DRAM bank.

More formally, I am trying to find functions $f_i$ for $i=1..k$ with $k \geq 6 = log_2(64)$ that takes as an input a 32-bit address [1] and whose resulting bits concatenated build an index (a unique sequence, e.g., 010011 for $f_1=0$, $f_2=1$, $f_3=0$ etc.) that assigns the address to one of the 64 sets. I have determined this number of sets with another approach (latency measurement) and I am sure this is correct.

There is not much known about $f_i$ except that

  • it most probably consists only of XORs (because they can be implemented very efficient in HW, they are also used for cache functions, and they map addresses uniformly),
  • it considers only some bits of the mask 0x3ff7c000 (however, taking all $f_i$ should cover all bits in 0x3ff7c000 assuming that this bit mask is correct),
  • and it could be that different $f_i$ are combined, e.g., bit 0 of the set index is true iff. $f_i(a) \land f_j(a)$ for $i\neq j$ and an address $a$

I have an exhaustive list of bit combinations that map to the different sets. In other words, if I have an address $a$ and apply all combinations of the set bits in 0x3ff7c000 to the address (i.e., replace these bits of the address), then I end up with following combinations in the same set:

00100010000000000000000000000000
00100000001000000000000000000000
00100000000000010000000000000000
00010001000000000000000000000000
00010000000100000000000000000000
00010000000000001000000000000000
00001000100000000000000000000000
00001000000001000000000000000000
00001000000000000100000000000000
00000100000000100000000000000000
00000010001000000000000000000000
00000010000000010000000000000000
00000001000100000000000000000000
00000001000000001000000000000000
00000000100001000000000000000000
00000000100000000100000000000000
00000000001000010000000000000000
00000000000100001000000000000000
00000000000001000100000000000000
... many more ...

This list was built using a side-channel (again, latency) and it could be that there are very few combinations (~5%) that are actually wrong.

Now my question is: is there an existing approach to determine the underlying function of these combinations? In fact, I tried brute-forcing because this is how these functions were reverse-engineered earlier but it did not work out, even. That's why I assume that the functions have gotten more complex or maybe they even combine different of them.

So far, I have tried to eliminate redundant combinations by checking linear independence but the result did not really help to find the functions. I also tried to apply the heuristic optimizer ESPRESSO on the combinations to see if it can simplify the entries but it was not successful.

I would appreciate any hints on how to proceed with that problem.

[1]: Actually, it is a 64-bit address but we can ignore that here because based on previous reverse-engineering we can assume that only the lower 32-bit of the address are relevant.

EDIT: There is a really nice paper titled "XOR-based Hash Functions" by Vandierendonck and De Bosschere that describes how these functions are constructed and their properties. I'm now trying to figure out how this can help in reverse-engineering such functions as I couldn't find any literature on that.