Input: Start instruction start_ins, end instruction end_ins |
Output: The constructed partial control flow graph and the possible execution paths |
(1) | Construct the node of basic block that contains start_ins, and push it into the aided stack stack_dfs. |
(2) | while stack_dfs is not empty do |
(3) | Get the top node block from stack_dfs. |
(4) | if block is parsed then |
(5) | if block contains end_ins then |
(6) | Save the traversed nodes, and pop block from stack_dfs. |
(7) | else if all the adjacent nodes of block are visited then |
(8) | Pop block from stack_dfs, mark all adjacent nodes as non-visited. |
(9) | else |
(10) | Get the adjacent node that is not visited, and push it into stack_dfs. |
(11) | Check and mark the loops in the traversed nodes. |
(12) | end |
(13) | else |
(14) | Disassemble and parse block |
(15) | while Get instruction ins from block successfully do |
(16) | if ins is a system call instruction or has memory operations then |
(17) | Mark block as abort |
(18) | break |
(19) | else if ins is a direct unconditional jump instruction then |
(20) | Construct the node of target block, and push it to stack_dfs |
(21) | break |
(22) | else if ins is a conditional branch instruction then |
(23) | Construct all successor nodes of block, and push them to stack_dfs |
(24) | break |
(25) | else if ins is an indirect branch instruction or other transfers then |
(26) | Mark block as pending, and save the traversed nodes and execution paths |
(27) | break |
(28) | else if ins is the end_ins then |
(29) | Mark block as the end |
(30) | break |
(31) | else |
(32) | Save the parse result to block |
(33) | end |
(34) | end |
(35) | end |
(36) | end |