Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,6 @@ vcomp110.dll
# This file should be generated just before compile the program.
# i#20 For some reason the script can not generate this file at Appveyor site. Let's ignore it for a while.
# VERSION_NUMBER

src_for_ida9
test
13 changes: 6 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Ponce works on Windows, Linux and OSX natively!
### Use cases

* **Exploit development**: Ponce can help you create an exploit in a far more efficient manner as the exploit developer may easily see what parts of memory and which registers you control, as well as possible addresses which can be leveraged as ROP gadgets.
* **Malware Analysis**: Another use of Ponce is related to malware code. Analyzing the commands a particular family of malware supports is easily determined by symbolizing a simple known command and negating all the conditions where the command is being checked.
* **Malware Analysis**: Another use of Ponce is related to malware code. Analyzing the commands a particular family of malware supports is easily determined by symbolizing a simple known command and negating all the conditions where the command is being checked.
* **Protocol Reversing**: One of the most interesting Ponce uses is the possibility of recognizing required magic numbers, headers or even entire protocols for controlled user input. For instance, Ponce can help you to list all the accepted arguments for a given command line binary or extract the file format required for a specific file parser.
* **CTF**: Ponce speeds up the process of reverse engineer binaries during CTFs. As Ponce is totally integrated into IDA you don't need to worry about setup timing. It's ready to be used!

Expand All @@ -40,7 +40,7 @@ The plugin will automatically run, guiding you through the initial configuration
### Use modes

* **Tainting engine**: This engine is used to determine at every step of the binary's execution which parts of memory and registers are controllable by the user input.
* **Symbolic engine**: This engine maintains a symbolic state of registers and part of memory at each step in a binary's execution path.
* **Symbolic engine**: This engine maintains a symbolic state of registers and part of memory at each step in a binary's execution path.

### Examples

Expand Down Expand Up @@ -154,7 +154,7 @@ Yes, you can natively use Ponce in IDA for Windows or remotely attach to a Linux

In our tests we reach to process 3000 instructions per second. We plan to use the PIN tracer IDA offers to increase the speed.

#### Something is not working!
#### Something is not working

Open an [issue](https://github.com/illera88/Ponce/issues), we will solve it ASAP ;\)

Expand All @@ -166,7 +166,7 @@ Sure! Please do pull requests and work in the opened issues. We will pay you in

Concolic execution and Ponce have some problems:

* Symbolic memory load/write: When the index used to read a memory value is symbolic like in `x = aray[symbolic_index]` some problems arise that could lead on the loose of track of the tainted/symbolized user controled input.
* Symbolic memory load/write: When the index used to read a memory value is symbolic like in `x = aray[symbolic_index]` some problems arise that could lead on the loose of track of the tainted/symbolized user controled input.
* Triton doesn't work very well with [floating point instructions](https://github.com/illera88/Ponce/issues/59).
* Concolic execution only analyzed the executed instructions. That means that symbolic tracking is lost in cases like the following:

Expand All @@ -184,6 +184,5 @@ Concolic execution and Ponce have some problems:

### Authors

* Alberto Garcia Illera \([@algillera](https://twitter.com/algillera)\) agarciaillera@gmail.com
* Francisco Oca \([@francisco\_oca](https://twitter.com/francisco_oca)\) francisco.oca.gonzalez@gmail.com

* Alberto Garcia Illera \([@algillera](https://twitter.com/algillera)\) <agarciaillera@gmail.com>
* Francisco Oca \([@francisco\_oca](https://twitter.com/francisco_oca)\) <francisco.oca.gonzalez@gmail.com>
36 changes: 23 additions & 13 deletions src/actions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,11 @@ struct ah_taint_symbolize_memory_t : public action_handler_t
current_ea = ctx->cur_value;
}
#endif
#if IDA_SDK_VERSION >= 900
else if (ctx->widget_type == BWN_HEXVIEW) {
#else
else if (ctx->widget_type == BWN_DUMP) {
#endif
if (ctx->cur_flags & ACF_HAS_SELECTION){ // Only if there has been a valid selection
//We get the selection bounds from the action activation context
auto selection_starts = ctx->cur_sel.from.at->toea();
Expand All @@ -183,6 +187,7 @@ struct ah_taint_symbolize_memory_t : public action_handler_t
current_ea = selection_starts;
}
}


#if IDA_SDK_VERSION >= 740
else if (ctx->widget_type == BWN_CPUREGS) {
Expand Down Expand Up @@ -253,9 +258,14 @@ struct ah_taint_symbolize_memory_t : public action_handler_t
}
action_to_take = is_debugger_on() ? AST_ENABLE : AST_DISABLE;
}
#if IDA_SDK_VERSION >= 900
else if (action_update_ctx_t->widget_type == BWN_HEXVIEW) {
#else
else if (action_update_ctx_t->widget_type == BWN_DUMP) {
action_to_take = is_debugger_on() ? AST_ENABLE : AST_DISABLE;
#endif
action_to_take = is_debugger_on() ? AST_ENABLE : AST_DISABLE;
}

#if IDA_SDK_VERSION >= 730
else if (action_update_ctx_t->widget_type == BWN_STKVIEW) {
if (is_mapped(action_update_ctx_t->cur_value)) {
Expand Down Expand Up @@ -838,11 +848,11 @@ struct ah_enable_disable_tracing_t : public action_handler_t
if (is_debugger_on()) {
//We are using this event to change the text of the action
if (ponce_runtime_status.runtimeTrigger.getState()) {
update_action_label(ctx->action, "Disable ponce tracing");
update_action_label(ctx->action, "[Ponce] Disable ponce tracing");
update_action_icon(ctx->action, 62);
}
else {
update_action_label(ctx->action, "Enable ponce tracing");
update_action_label(ctx->action, "[Ponce] Enable ponce tracing");
update_action_icon(ctx->action, 61);
}
return AST_ENABLE;
Expand All @@ -855,7 +865,7 @@ static ah_enable_disable_tracing_t ah_enable_disable_tracing;
//We need to define this struct before the action handler because we are using it inside the handler
action_desc_t action_IDA_enable_disable_tracing = ACTION_DESC_LITERAL(
"Ponce:enable_disable_tracing",
"Enable ponce tracing", //The action text.
"[Ponce] Enable ponce tracing", //The action text.
&ah_enable_disable_tracing, //The action handler.
"Ctrl+Shift+E", //Optional: the action shortcut
"Enable or Disable the ponce tracing", //Optional: the action tooltip (available in menus/toolbar)
Expand Down Expand Up @@ -1000,7 +1010,7 @@ static ah_run_until_symbolic_t ah_run_until_symbolic;
//We need to define this struct before the action handler because we are using it inside the handler
action_desc_t action_IDA_run_until_symbolic = ACTION_DESC_LITERAL(
"Ponce:run_until_symbolic_branch",
"Run until symbolic condition", //The action text.
"[Ponce] Run until symbolic condition", //The action text.
&ah_run_until_symbolic, //The action handler.
"Ctrl+Shift+F9", //Optional: the action shortcut
"Continue running and stop on next symbolic condition", //Optional: the action tooltip (available in menus/toolbar)
Expand All @@ -1016,18 +1026,18 @@ struct IDA_actions action_list[] =

{ &action_IDA_run_until_symbolic, { BWN_DISASM, __END__ }, "" },

{ &action_IDA_taint_symbolize_register, {0}, "Symbolic or taint/"},
{ &action_IDA_taint_symbolize_memory, {0}, "Symbolic or taint/" },
{ &action_IDA_taint_symbolize_register, {0}, "[Ponce] Symbolic or taint/"},
{ &action_IDA_taint_symbolize_memory, {0}, "[Ponce] Symbolic or taint/" },

{ &action_IDA_negate_and_inject, { BWN_DISASM, __END__ }, "SMT Solver/" },
{ &action_IDA_negate_inject_and_restore, { BWN_DISASM, __END__ }, "SMT Solver/" },
{ &action_IDA_negate_and_inject, { BWN_DISASM, __END__ }, "[Ponce] SMT Solver/" },
{ &action_IDA_negate_inject_and_restore, { BWN_DISASM, __END__ }, "[Ponce] SMT Solver/" },
// Solve formula is handled separatly to be more user friendly
// But still we want to register it in advance so it is always disable, so we define no views
{ &action_IDA_solve_formula_sub, { __END__ }, "SMT Solver/" },
{ &action_IDA_solve_formula_sub, { __END__ }, "[Ponce] SMT Solver/" },

{ &action_IDA_createSnapshot, { BWN_DISASM, __END__ }, "Snapshot/"},
{ &action_IDA_restoreSnapshot, { BWN_DISASM, __END__ }, "Snapshot/" },
{ &action_IDA_deleteSnapshot, { BWN_DISASM, __END__ }, "Snapshot/" },
{ &action_IDA_createSnapshot, { BWN_DISASM, __END__ }, "[Ponce] Snapshot/"},
{ &action_IDA_restoreSnapshot, { BWN_DISASM, __END__ }, "[Ponce] Snapshot/" },
{ &action_IDA_deleteSnapshot, { BWN_DISASM, __END__ }, "[Ponce] Snapshot/" },

{ &action_chooser_comment, { BWN_CHOOSER, __END__ }, "" },
{ &action_chooser_add_constrain, { BWN_CHOOSER, __END__ }, "" },
Expand Down
20 changes: 12 additions & 8 deletions src/actions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,22 @@
#define __END__ -1

/* Depending on the IDA version the SDK allows or not using some of the fetures we have*/
#if IDA_SDK_VERSION < 730
const int ponce_banner_views[] = { BWN_DISASM, BWN_DUMP, BWN_CHOOSER, __END__ };
const int ponce_taint_symbolize_mem_views[] = { BWN_DISASM, BWN_DUMP, __END__ };
const int ponce_taint_symbolize_reg_views[] = { BWN_DISASM, BWN_DUMP, __END__ };
#elif IDA_SDK_VERSION == 730
const int ponce_banner_views[] = { BWN_DISASM, BWN_DUMP, BWN_STKVIEW, BWN_CHOOSER, __END__ };
const int ponce_taint_symbolize_mem_views[] = { BWN_DISASM, BWN_DUMP, BWN_STKVIEW, __END__ };
const int ponce_taint_symbolize_reg_views[] = { BWN_DISASM, BWN_DUMP, BWN_STKVIEW, __END__ };
#if IDA_SDK_VERSION >= 900
const int ponce_banner_views[] = { BWN_DISASM, BWN_CPUREGS, BWN_HEXVIEW, BWN_STKVIEW, BWN_CHOOSER, __END__ };
const int ponce_taint_symbolize_mem_views[] = { BWN_DISASM, BWN_CPUREGS, BWN_HEXVIEW, BWN_STKVIEW, __END__ };
const int ponce_taint_symbolize_reg_views[] = { BWN_DISASM, BWN_CPUREGS, BWN_HEXVIEW, BWN_STKVIEW, __END__ };
#elif IDA_SDK_VERSION >= 740
const int ponce_banner_views[] = { BWN_DISASM, BWN_CPUREGS, BWN_DUMP, BWN_STKVIEW, BWN_CHOOSER, __END__ };
const int ponce_taint_symbolize_mem_views[] = { BWN_DISASM, BWN_CPUREGS, BWN_DUMP, BWN_STKVIEW, __END__ };
const int ponce_taint_symbolize_reg_views[] = { BWN_DISASM, BWN_CPUREGS, BWN_DUMP, BWN_STKVIEW, __END__ };
#elif IDA_SDK_VERSION == 730
const int ponce_banner_views[] = { BWN_DISASM, BWN_DUMP, BWN_STKVIEW, BWN_CHOOSER, __END__ };
const int ponce_taint_symbolize_mem_views[] = { BWN_DISASM, BWN_DUMP, BWN_STKVIEW, __END__ };
const int ponce_taint_symbolize_reg_views[] = { BWN_DISASM, BWN_DUMP, BWN_STKVIEW, __END__ };
#elif IDA_SDK_VERSION < 730
const int ponce_banner_views[] = { BWN_DISASM, BWN_DUMP, BWN_CHOOSER, __END__ };
const int ponce_taint_symbolize_mem_views[] = { BWN_DISASM, BWN_DUMP, __END__ };
const int ponce_taint_symbolize_reg_views[] = { BWN_DISASM, BWN_DUMP, __END__ };
#endif

struct IDA_actions {
Expand Down
4 changes: 2 additions & 2 deletions src/blacklist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,12 @@ void concretizeAndUntaintVolatileRegisters()
#if defined(__i386) || defined(_M_IX86)
char const* volatile_regs[] = { "eax", "ecx", "edx" };
#elif defined(__x86_64__) || defined(_M_X64)
char const* volatile_regs[] = { "rax", "rcx", "rdx", "r8", "r8", "r10", "r11", "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15" };
char const* volatile_regs[] = { "rax", "rcx", "rdx", "r8", "r9", "r10", "r11", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5" };
#endif

for (const auto& [reg_id, reg] : tritonCtx.getAllRegisters())
{
for (auto i = 0; i < sizeof(volatile_regs) / sizeof(char*); i++) {
for (size_t i = 0; i < sizeof(volatile_regs) / sizeof(char*); i++) {
if (strcmp(reg.getName().c_str(), volatile_regs[i]) == 0) {
tritonCtx.concretizeRegister(reg);
tritonCtx.untaintRegister(reg);
Expand Down
Loading