问题
I want to somehow get the "number of executed assembler instructions" from a binary. Consider the following piece of code:
if(password[0] == 'p') {
if(password[1] == 'a') {
......
printf("Correct Password\n");
}
}
Then if I would start the program with e.g. "abc" it would not take the first branch, thus it would execute less instructions. If I put in "pbc" it would take the first branch, thus it would execute a little bit more (about 4-5) instructions. (This is some Research for CTF (Capture The Flag) files). So my idea is instead of reversing a binary and trying to understand the algorithm, I use the faster approach in counting the number of executed assembler instructions for different setups (like different characters or password lengths and so on to see if I can take another branch using another input thus creating more assembler instructions).
My basic idea would be to write a simple debugger just placing a int3 after the current Instruction, increment there a counter, disassembler the next instruction and place a int3 right after this instruction (strong simplified version of my idea).
Is there any program/library/... which already done that stuff? (Because I see some problemens when the program deals with signals, ...)
(I already tried using high precises timers to measure the time, but that was a complete fail because of the difference are just 4-5 instructions)
回答1:
The Linux "perf" tool can use hardware performance counters to give you precise numbers for lots of things including instructions executed.
$ perf stat true
Performance counter stats for 'true':
0.183734 task-clock # 0.314 CPUs utilized
0 context-switches # 0.000 M/sec
0 CPU-migrations # 0.000 M/sec
118 page-faults # 0.642 M/sec
627,313 cycles # 3.414 GHz
396,604 stalled-cycles-frontend # 63.22% frontend cycles idle
268,222 stalled-cycles-backend # 42.76% backend cycles idle
404,935 instructions # 0.65 insns per cycle
# 0.98 stalled cycles per insn
75,949 branches # 413.364 M/sec
3,602 branch-misses # 4.74% of all branches
0.000584503 seconds time elapsed
To get only user-mode instructions:
$ perf stat -e instructions:u true
Performance counter stats for 'true':
92,687 instructions:u # 0.00 insns per cycle
0.000520925 seconds time elapsed
I see a little bit of variance in this though, like 5-6 instructions. Not sure if that's real or just a measurement artifact. To get more reliable results, I think of turning to a simulator like Valgrind. I had some luck getting stable instruction counts that only vary by 1 instruction from these two commands:
$ valgrind --tool=callgrind true
$ valgrind --tool=exp-bbv true
来源:https://stackoverflow.com/questions/16312270/how-to-measure-number-of-executed-assembler-instructions