divtest.asm

generates a CPU signature based on the DIV test

Author

Marcel Sondaar

License

Public Domain

Summary
divtest.asmgenerates a CPU signature based on the DIV test
Functions
cpu_divtestperforms an DIV test to get a processor’s signature.

Functions

cpu_divtest

performs an DIV test to get a processor’s signature.

This is an useful method to distinguish processors without CPUID support, although it can help in detecting spoofed CPUID info (including emulators)

in

stack(1)pointer to the variable to store the first result
stack(2)pointer to the variable to store the second result

out

[ stack(1) ]the result of a classic DIV test
[ stack(2) ]the result of the complement DIV test

note that you should not supply NULL pointers as these are filled without checking

the first result contains the flags after the DIV test with the user flags cleared. the second result contains the flags after the DIV test with the same flags set.  AND these results with 0x8D5 to get the sensitive flags (first return value AND 0x8D5 will yield the classic DIVtest signature)

the advantage of returning both values is that we are able to check which bits are set, cleared, toggled, or untouched

signatures found

 CPU                | classic | second |  set  | cleared | maintained | toggled
--------------------+---------+--------+-------+---------+------------+---------
Intel Pentium 1 | 0x095 | 0x095 | 0x095 | 0x840 | 0x000 | 0x000
Intel Pentium Pro | 0x000 | 0x8D5 | 0x000 | 0x000 | 0x8D5 | 0x000
Intel Pentium II | 0x000 | 0x8D5 | 0x000 | 0x000 | 0x000 | 0x000
--------------------+---------+--------+-------+---------+------------+---------
AMD Am5x85 | 0x095 | 0x095 | 0x095 | 0x840 | 0x000 | 0x000
AMD K6 | 0x010 | 0x811 | 0x010 | 0x0C4 | 0x801 | 0x000
AMD64 3200+ | 0x010 | 0x811 | 0x010 | 0x0C4 | 0x801 | 0x000
AMD Phenom | 0x010 | 0x811 | 0x010 | 0x0C4 | 0x801 | 0x000
--------------------+---------+--------+-------+---------+------------+---------
Cyrix 6x86 | 0x000 | 0x801 | 0x000 | 0x0D4 | 0x801 | 0x000
Cyrix 6x86MX | 0x000 | 0x801 | 0x000 | 0x0D4 | 0x801 | 0x000
--------------------+---------+--------+-------+---------+------------+---------
Bochs ** | 0x000 | 0x8D5 | 0x000 | 0x000 | 0x8D5 | 0x000
Qemu | 0x000 | 0x8D5 | 0x000 | 0x000 | 0x8D5 | 0x000
--------------------+---------+--------+-------+---------+------------+---------
intel 386/486 * | 0x095 | - | - | - | - | -
amd k5 * | 0x020 | - | - | - | - | -
cyrix * | 0x040 | - | - | - | - | -
nexgen * | 0x004 | - | - | - | - | -
--------------------+---------+--------+-------+---------+------------+---------
| 0x000 | 0x000 | 0x000 | 0x000 | 0x000 | 0x000

signatures marked with * come from http://grafi.ii.pw.edu.pl/gbm/x86/div.html - Since this site only lists classic results, I dont have full signature info for these.

Bochs (**) emulates by default a div instruction that does not touch the flags.  However, there exist patches that alter this behaviour on purpose, giving it the signature of a specific processor, or one which is made up by the user.