diff --git a/P1_utility.cpp b/P1_utility.cpp index 83d12539cc820df43ce9515e48a05b9bafda8851..a5ae1c13b65ac586bb823e496bf66b24b9fb3a83 100644 --- a/P1_utility.cpp +++ b/P1_utility.cpp @@ -34,8 +34,12 @@ Instruction_t* P1_insertAssemblyBefore(FileIR_t* virp, Instruction_t* first, str Instruction_t* newInsn = IRDB_SDK::insertAssemblyBefore(virp, first, assembly, target); Function_t* func = newInsn->getFunction(); inserted_instr[func].insert(newInsn); - inserted_addr[func].insert(newInsn->getAddress()); - return newInsn; + inserted_addr[func].insert(newInsn->getAddress()); + if (verbose_log) + { + cout << "P1_insertAssemblyBefore is adding: " << assembly << endl; + } + return newInsn; } @@ -45,7 +49,11 @@ Instruction_t* P1_insertAssemblyBefore(FileIR_t* virp, Instruction_t* first, str Function_t* func = newInsn->getFunction(); inserted_instr[func].insert(newInsn); inserted_addr[func].insert(newInsn->getAddress()); - return newInsn; + if (verbose_log) + { + cout << "P1_insertAssemblyBefore is adding: " << assembly << endl; + } + return newInsn; } @@ -55,7 +63,11 @@ Instruction_t* P1_insertAssemblyAfter(FileIR_t* virp, Instruction_t* first, stri Function_t* func = newInsn->getFunction(); inserted_instr[func].insert(newInsn); inserted_addr[func].insert(newInsn->getAddress()); - return newInsn; + if (verbose_log) + { + cout << "P1_insertAssemblyAfter is adding: " << assembly << endl; + } + return newInsn; } @@ -65,7 +77,11 @@ Instruction_t* P1_insertAssemblyAfter(FileIR_t* virp, Instruction_t* first, stri Function_t* func = newInsn->getFunction(); inserted_instr[func].insert(newInsn); inserted_addr[func].insert(newInsn->getAddress()); - return newInsn; + if (verbose_log) + { + cout << "P1_insertAssemblyAfter is adding: " << assembly << endl; + } + return newInsn; } diff --git a/PNMain.cpp b/PNMain.cpp index 33476c07df27f20dede319bb321ee60168669502..575de9f812580a0761aaee565dee298c5b7bf21a 100644 --- a/PNMain.cpp +++ b/PNMain.cpp @@ -355,24 +355,33 @@ void parseYAMLNode(YAML::Node &currNode, PNOptions *currOptions) } #endif -#if 0 // canary types of float, top, and bottom do not seem to exist yet YAML::Node canarytypenode = currNode["canary_type"]; if (!canarytypenode.IsNull() && canarytypenode.IsDefined()) { string canarytypevalstr = canarytypenode.as<std::string>(); - if (0 != canarytypevalstr.compare("")) + if (verbose_log) { - // A particular auto_initialize canary value is specified. - int new_autoinit_value = stoi(autoinitvalstr, nullptr, 10); - int old_autoinit_value = currOptions->getCanaryValue(); - if (new_autoinit_value != old_autoinit_value) - { - cout << "YAML: Changing auto_init canary value from " << old_autoinit_value << " to " << new_autoinit_value << endl; - currOptions->setCanaryValue(new_autoinit_value); - } + cout << "Found canary_type: " << canarytypevalstr << endl; + } + if (0 == canarytypevalstr.compare("top")) + { + currOptions->setCanaryType(C_CANARY_TOP); + } + else if (0 == canarytypevalstr.compare("float")) + { + currOptions->setCanaryType(C_CANARY_FLOATING); + } + else if (0 == canarytypevalstr.compare("bottom")) + { + currOptions->setCanaryType(C_CANARY_BOTTOM); + } + else + { + cout << "ERROR: Invalid canary type: " << canarytypevalstr << endl; + cout << "Keeping default canary type " << endl; } } -#endif + return; } // end of parseYAMLNode() diff --git a/PNStackLayout.cpp b/PNStackLayout.cpp index d276e769bdbec96ff236b194f147d813845a1cb5..122278269f550ec01b016892a735483eb5ee9ebc 100644 --- a/PNStackLayout.cpp +++ b/PNStackLayout.cpp @@ -393,7 +393,7 @@ void PNStackLayout::AddRandomPadding(bool isaligned) if (verbose_log) { cerr << "Last object size=0x" << hex << last_pad << endl; - cerr << "altered_aloc_size=0x" << hex << altered_alloc_size << endl; + cerr << "altered_alloc_size=0x" << hex << altered_alloc_size << endl; cerr << "total_padding=0x" << hex << total_padding << endl; } @@ -412,7 +412,7 @@ void PNStackLayout::AddRandomPadding(bool isaligned) cerr << "PNStackLayout: AddPadding(): " << ToString() << endl; for (unsigned int i = 0; i < mem_objects.size(); ++i) { - cerr << "\tOffset = " << mem_objects[i]->getOffset() << " Size = " << mem_objects[i]->getSize() << + cerr << dec << "\tOffset = " << mem_objects[i]->getOffset() << " Size = " << mem_objects[i]->getSize() << " Padding = " << mem_objects[i]->GetPaddingSize() << " displ = " << mem_objects[i]->GetDisplacement() << endl; } } diff --git a/PNTransformDriver.cpp b/PNTransformDriver.cpp index 52976fba0618c85d8f0fe90ac99165b23e6d087f..7078adfe15019d309fe81d88398df71fb023681e 100644 --- a/PNTransformDriver.cpp +++ b/PNTransformDriver.cpp @@ -118,7 +118,7 @@ PNTransformDriver::PNTransformDriver(VariantID_t *pidp,string BED_script, pqxxDB orig_virp = NULL; this->BED_script = BED_script; do_canaries = true; - do_floating_canary = false; + this->do_floating_canary = false; do_align = false; no_validation_level = -1; coverage_threshold = -1; @@ -2244,6 +2244,7 @@ bool PNTransformDriver::Canary_Rewrite(PNStackLayout *orig_layout, Function_t *f //TODO: hack for TNE, assuming all virp is orig_virp now. FileIR_t *virp = orig_virp; + // TODO: Should we getFuncOptions inside Sans_Canary_Rewrite() to allow overrides there? if (!orig_layout->IsCanarySafe()) return Sans_Canary_Rewrite(orig_layout,func); @@ -2253,28 +2254,45 @@ bool PNTransformDriver::Canary_Rewrite(PNStackLayout *orig_layout, Function_t *f vector<PNRange*> mem_objects = layout->GetRanges(); + PNOptions *funcOptions = getFuncOptions((int32_t) func->getBaseID()); + + unsigned int paddingAdded = (layout->GetAlteredAllocSize() - layout->GetOriginalAllocSize()); + bool floatingCanaryFlag = (funcOptions->getCanaryType() == C_CANARY_FLOATING); + bool topCanaryFlag = (funcOptions->getCanaryType() == C_CANARY_TOP); + if (verbose_log) + { + cout << "Padding added: " << paddingAdded << " topCanaryFlag: " << topCanaryFlag << endl; + } + for (unsigned int i = 0; i < mem_objects.size(); ++i) { canary c; int floating_canary_offset = 0; - if (do_floating_canary) + int reg_size = get_saved_reg_size(); + + if (floatingCanaryFlag) { // nb: get_saved_reg_size is 4 or 8 depending on architecture - int reg_size = get_saved_reg_size(); - floating_canary_offset = (rand() % (layout->GetAlteredAllocSize() - layout->GetOriginalAllocSize() - reg_size)); + floating_canary_offset = (rand() % (paddingAdded - reg_size)); floating_canary_offset -= (floating_canary_offset % reg_size); assert(floating_canary_offset >= 0); - c.floating_offset = floating_canary_offset; - } - else - { - c.floating_offset = 0; } + c.floating_offset = floating_canary_offset; + // This code assumes a bottom-of-the-padding canary or a floating (middle of padding) canary. c.esp_offset = mem_objects[i]->getOffset() + mem_objects[i]->GetDisplacement() + mem_objects[i]->getSize(); c.esp_offset += floating_canary_offset; + if (topCanaryFlag && (0 < paddingAdded)) + { + if (verbose_log) + { + cout << "Canary_Rewrite is using a top canary_type " << endl; + } + assert(paddingAdded >= reg_size); + c.esp_offset += (paddingAdded - reg_size); + } assert(c.esp_offset >= 0); diff --git a/globals.h b/globals.h index 371dc88339f9cf9ba1edc61730e5fc16de05086a..62101cbb7468e212c41bc4001c09e66fd12209d9 100644 --- a/globals.h +++ b/globals.h @@ -47,7 +47,11 @@ enum mitigation_policy P_HARD_EXIT }; - +enum canaryTypeEnum { + C_CANARY_TOP, + C_CANARY_BOTTOM, + C_CANARY_FLOATING +}; class PNOptions { @@ -70,6 +74,7 @@ class PNOptions spri_validate=false; detection_policy=P_HARD_EXIT; detection_exit_code=DEFAULT_DETECTION_EXIT_CODE; + canary_type = C_CANARY_BOTTOM; } void setMinStackPadding(int val) { min_stack_padding = val; } @@ -120,6 +125,8 @@ class PNOptions mitigation_policy getDetectionPolicy() const { return detection_policy; } unsigned getDetectionExitCode() const { return detection_exit_code; } void setDetectionExitCode(unsigned p_exitCode) { detection_exit_code = p_exitCode; } + canaryTypeEnum getCanaryType(void) const { return canary_type; }; + void setCanaryType(const canaryTypeEnum newType) { canary_type = newType; }; private: int min_stack_padding; @@ -140,6 +147,7 @@ class PNOptions std::set<std::string> canary_functions; mitigation_policy detection_policy; + canaryTypeEnum canary_type; unsigned detection_exit_code; }; @@ -147,7 +155,7 @@ extern PNOptions *pn_options; // Get YAML override options for FuncAddress and insert them into a copy of // the global PNOptions and return it. If no overrides, return global options. -PNOptions *getFuncOptions(int32_t FuncID); +extern PNOptions *getFuncOptions(int32_t FuncID); #endif