技术编程|自动重构Meterpreter绕过杀软·续( 四 )


这是最琐碎的部分 。目的是用随机标识符替换AST中的MessageBoxA 。此随机变量的初始化会在后续部分中完成 。 bool ApiMatchHandler::handleCallExpr(const CallExpr *CallExpression, clang::ASTContext *const pContext) {// generate a random variable namestd::string Replacement = Utils::translateStringToIdentifier(_ApiName);// inject Run-time dynamic linkingif (!addGetProcAddress(CallExpression, pContext, Replacement, _ApiName))return false;// MessageBoxA -> random identifier generated abovereturn replaceIdentifier(CallExpression, _ApiName, Replacement);}
ReplaceText Clang AP用于重命名函数标识符:bool ApiMatchHandler::replaceIdentifier(const CallExpr *CallExpression, const std::string &ApiName,const std::string &NewIdentifier) {return this->ASTRewriter->ReplaceText(CallExpression->getBeginLoc(), ApiName.length(), NewIdentifier);}插入 LoadLibrary / GetProcAddress
为我们要添加的API注入运行时动态链接是一个多步骤过程:我们可以选择将API原型插入翻译单元的顶部或封闭函数中 。为了更方便简单 , 我们选择后者 , 但是我们需要确保它没有被添加 , 以防在同一个函数中多次调用该API(如果后面调用相同的API , 就会发生这种情况) 。 插入行 HANDLE
LoadLibrary(
);插入对GetProcAddress的调用 。
当然 , 为了避免在执行此操作时插入明显的敏感字符串 , 必须将每个字符串写为堆栈字符串的形式 。这会使代码阅读起来有些冗杂 , 但并太复杂:bool ApiMatchHandler::addGetProcAddress(const clang::CallExpr *pCallExpression, clang::ASTContext *const pContext,const std::string &NewIdentifier, std::string &ApiName) {SourceRange EnclosingFunctionRange = findInjectionSpot(pContext, clang::ast_type_traits::DynTypedNode(),*pCallExpression, 0);std::stringstream Result;// add function prototype if not already addedif(std::find(TypedefAdded.begin(), TypedefAdded.end(), pCallExpression->getDirectCallee()) == TypedefAdded.end()) {Result << "\t" << _TypeDef << "\n";}// add LoadLibrary with obfuscated stringsstd::string LoadLibraryVariable = Utils::translateStringToIdentifier(_Library);std::string LoadLibraryString = Utils::generateVariableDeclaration(LoadLibraryVariable, _Library);std::string LoadLibraryHandleIdentifier = Utils::translateStringToIdentifier("hHandle_"+_Library);Result << "\t" << LoadLibraryString << std::endl;Result << "\tHANDLE " << LoadLibraryHandleIdentifier << " = LoadLibrary(" << LoadLibraryVariable << ");\n";// add GetProcAddress with obfuscated string: TypeDef NewIdentifier = (TypeDef) GetProcAddress(handleIdentifier, ApiName)std::string ApiNameIdentifier = Utils::translateStringToIdentifier(ApiName);std::string ApiNameDecl = Utils::generateVariableDeclaration(ApiNameIdentifier, ApiName);Result << "\t" << ApiNameDecl << "\n";Result << "\t_ "<< ApiName << " " << NewIdentifier << " = (_" << ApiName << ") GetProcAddress("<< LoadLibraryHandleIdentifier << ", " << ApiNameIdentifier <
getDirectCallee());// add everything at the beginning of the function.return !(ASTRewriter->InsertText(EnclosingFunctionRange.getBegin(), Result.str()));}测试git clone https://github.com/scrt/avcleanermkdir avcleaner/CMakeBuild && cd avcleaner/CMakeBuildcmake ..makecd ..


推荐阅读