Skip to content

Commit

Permalink
Panics for soft error handling, some refactor and comments
Browse files Browse the repository at this point in the history
  • Loading branch information
tudor-timcu committed May 23, 2024
1 parent 3a0a476 commit b0e18db
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 21 deletions.
33 changes: 21 additions & 12 deletions src/extension/aikido.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,21 @@ struct FUNCTION_HANDLERS {
zif_handler original_handler;
};

#define AIKIDO_REGISTER_HANDLER(function_name) { std::string(#function_name), { handle_##function_name, nullptr } }
/*
Macro for registering an Aikido handler in the HOOKED_FUNCTIONS map.
It takes as parameters the PHP function name to be hooked and C++ function
that should be called when that PHP function is executed.
The nullptr part is a placeholder where the original function handler from
the Zend framework will be stored at initialization when we run the hooking.
*/
#define AIKIDO_REGISTER_HANDLER_EX(function_name, function_pointer) { std::string(#function_name), { function_pointer, nullptr } }

/*
Shorthand version of AIKIDO_REGISTER_HANDLER_EX that constructs automatically the C++ function to be called.
For example, if function name is curl_init this macro will store { "curl_init", { handle_curl_init, nullptr } }.
*/
#define AIKIDO_REGISTER_HANDLER(function_name) { std::string(#function_name), { handle_##function_name, nullptr } }


unordered_map<std::string, FUNCTION_HANDLERS> HOOKED_FUNCTIONS = {
AIKIDO_REGISTER_HANDLER(curl_init),
Expand All @@ -44,16 +56,13 @@ unordered_map<std::string, FUNCTION_HANDLERS> HOOKED_FUNCTIONS = {
AIKIDO_REGISTER_HANDLER_EX(proc_open, handle_shell_execution)
};

#define AIKIDO_HANDLER_START(function_name) php_printf("[AIKIDO-C++] Handler called for \"" #function_name "\"!\n");
#define AIKIDO_HANDLER_END(function_name) HOOKED_FUNCTIONS[#function_name].original_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU);

#define AIKIDO_GET_FUNCTION_NAME() (ZSTR_VAL(execute_data->func->common.function_name))

#define AIKIDO_HANDLER_START_GENERIC() php_printf("[AIKIDO-C++] Handler called for \"%s\"!\n", AIKIDO_GET_FUNCTION_NAME());
#define AIKIDO_HANDLER_END_GENERIC() HOOKED_FUNCTIONS[AIKIDO_GET_FUNCTION_NAME()].original_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU);
#define AIKIDO_HANDLER_START() php_printf("[AIKIDO-C++] Handler called for \"%s\"!\n", AIKIDO_GET_FUNCTION_NAME());
#define AIKIDO_HANDLER_END() HOOKED_FUNCTIONS[AIKIDO_GET_FUNCTION_NAME()].original_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU);

ZEND_NAMED_FUNCTION(handle_curl_init) {
AIKIDO_HANDLER_START(curl_init);
AIKIDO_HANDLER_START();

zend_string *url = NULL;

Expand All @@ -62,7 +71,7 @@ ZEND_NAMED_FUNCTION(handle_curl_init) {
Z_PARAM_STR_OR_NULL(url)
ZEND_PARSE_PARAMETERS_END();

AIKIDO_HANDLER_END(curl_init);
AIKIDO_HANDLER_END();

if (Z_TYPE_P(return_value) != IS_FALSE) {
// Z_OBJ_P(return_value)
Expand All @@ -82,7 +91,7 @@ ZEND_NAMED_FUNCTION(handle_curl_init) {
}

ZEND_NAMED_FUNCTION(handle_curl_setopt) {
AIKIDO_HANDLER_START(curl_setopt);
AIKIDO_HANDLER_START();

zval *curlHandle = NULL;
zend_long options = 0;
Expand Down Expand Up @@ -115,11 +124,11 @@ ZEND_NAMED_FUNCTION(handle_curl_setopt) {
zend_tmp_string_release(tmp_str);
}

AIKIDO_HANDLER_END(curl_setopt);
AIKIDO_HANDLER_END();
}

ZEND_NAMED_FUNCTION(handle_shell_execution) {
AIKIDO_HANDLER_START_GENERIC();
AIKIDO_HANDLER_START();

zend_string *cmd = NULL;

Expand All @@ -144,7 +153,7 @@ ZEND_NAMED_FUNCTION(handle_shell_execution) {

GoOnEvent(shell_execution_event);

AIKIDO_HANDLER_END_GENERIC();
AIKIDO_HANDLER_END();
}

/* For compatibility with older PHP versions */
Expand Down
2 changes: 1 addition & 1 deletion src/lib/handle_function_executed.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func OnFunctionExecuted(data map[string]interface{}) string {
functionName := MustGetFromMap[string](data, "function_name")
parameters := MustGetFromMap[map[string]interface{}](data, "parameters")

ExitIfKeyDoesNotExistInMap(functionExecutedHandlers, functionName)
CheckIfKeyExists(functionExecutedHandlers, functionName)

return functionExecutedHandlers[functionName](parameters)
}
14 changes: 10 additions & 4 deletions src/lib/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import "C"
import (
"encoding/json"
"fmt"
"log"
)

type eventFunctionExecutedFn func(map[string]interface{}) string
Expand All @@ -14,19 +13,26 @@ var eventHandlers = map[string]eventFunctionExecutedFn{
}

//export OnEvent
func OnEvent(eventJson string) string {
func OnEvent(eventJson string) (outputJson string) {
defer func() {
if r := recover(); r != nil {
fmt.Println("[AIKIDO-GO] Recovered from panic:", r)
outputJson = "{}"
}
}()

fmt.Println("[AIKIDO-GO] OnEvent:", eventJson)

var event map[string]interface{}
err := json.Unmarshal([]byte(eventJson), &event)
if err != nil {
log.Fatalf("Error parsing JSON: %s", err)
panic(fmt.Sprintf("Error parsing JSON: %s", err))
}

eventName := MustGetFromMap[string](event, "event")
data := MustGetFromMap[map[string]interface{}](event, "data")

ExitIfKeyDoesNotExistInMap(eventHandlers, eventName)
CheckIfKeyExists(eventHandlers, eventName)

return eventHandlers[eventName](data)
}
Expand Down
8 changes: 4 additions & 4 deletions src/lib/utils.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package main

import (
"log"
"fmt"
"net/url"
)

func ExitIfKeyDoesNotExistInMap[K comparable, V any](m map[K]V, key K) {
func CheckIfKeyExists[K comparable, V any](m map[K]V, key K) {
if _, exists := m[key]; !exists {
log.Fatalf("Key %s does not exist in map!", key)
panic(fmt.Sprintf("Key %s does not exist in map!", key))
}
}

Expand All @@ -26,7 +26,7 @@ func GetFromMap[T any](m map[string]interface{}, key string) *T {
func MustGetFromMap[T any](m map[string]interface{}, key string) T {
value := GetFromMap[T](m, key)
if value == nil {
log.Fatalf("Error parsing JSON: key %s has incorrect type", key)
panic(fmt.Sprintf("Error parsing JSON: key %s does not exist or it has an incorrect type", key))
}
return *value
}
Expand Down

0 comments on commit b0e18db

Please sign in to comment.