Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to measure number of executed assembler instructions?

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)

like image 476
rené freing Avatar asked May 01 '13 03:05

rené freing


1 Answers

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
like image 115
Josh Haberman Avatar answered Sep 20 '22 22:09

Josh Haberman