Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
36ecd7e349 | ||
|
|
c49eaf9203 | ||
|
|
0859358c29 | ||
|
|
3f596a4041 | ||
|
|
cfb4e9461f |
@@ -0,0 +1,23 @@
|
||||
#ifndef BASE_FUNCTION_RESOLVER_H_
|
||||
#define BASE_FUNCTION_RESOLVER_H_
|
||||
namespace base {
|
||||
class FunctionResolver {
|
||||
public:
|
||||
explicit FunctionResolver(uint64_t base_addr) : base_addr_(base_addr) {}
|
||||
|
||||
template <typename FuncType>
|
||||
FuncType ResolveFunction(uint64_t offset) {
|
||||
return reinterpret_cast<FuncType>(base_addr_ + offset);
|
||||
}
|
||||
|
||||
private:
|
||||
uint64_t base_addr_;
|
||||
};
|
||||
|
||||
template<typename FuncType>
|
||||
auto CastFunction(FunctionResolver& resolver, uint64_t offset) {
|
||||
return resolver.ResolveFunction<FuncType>(offset);
|
||||
}
|
||||
|
||||
} // namespace base
|
||||
#endif
|
||||
@@ -30,7 +30,7 @@ add_subdirectory(../base base)
|
||||
|
||||
add_library(wxhelper SHARED ${CPP_FILES} ${ASM_FILES})
|
||||
|
||||
target_compile_definitions(wxhelper PRIVATE WECHAT_VERSION=391119)
|
||||
target_compile_definitions(wxhelper PRIVATE WECHAT_VERSION=391125)
|
||||
|
||||
# target_include_directories(wxhelper
|
||||
# PRIVATE ../base/src/include
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace wechat {
|
||||
#define V_3_9_9_43 39943
|
||||
#define V_3_9_10_19 391019
|
||||
#define V_3_9_11_19 391119
|
||||
#define V_3_9_11_25 391125
|
||||
#ifndef WECHAT_VERSION
|
||||
#error " WECHAT_VERSION not defined ."
|
||||
#endif
|
||||
@@ -467,6 +468,125 @@ const uint64_t kAddFriend = 0x1f3a350;
|
||||
const uint64_t kVerifyApply = 0x1f3a940;
|
||||
const uint64_t kDoDelContact = 0x2310120;
|
||||
|
||||
const uint64_t kGetSearchContactMgr = 0x1f9a730;
|
||||
const uint64_t kStartSearch = 0x22a4200;
|
||||
#elif WECHAT_VERSION == V_3_9_11_25
|
||||
const uint64_t kGetAccountServiceMgr = 0x1b50d00;
|
||||
const uint64_t kSyncMsg = 0xc39680;
|
||||
const uint64_t kSyncMsgNext = 0xc39680;
|
||||
const uint64_t kGetCurrentDataPath = 0x2248ce0;
|
||||
const uint64_t kGetAppDataSavePath = 0x25dc0e0;
|
||||
const uint64_t kGetSendMessageMgr = 0x1b4f500;
|
||||
const uint64_t kSendTextMsg = 0x22c2010;
|
||||
const uint64_t kFreeChatMsg = 0x1b50d80;
|
||||
|
||||
const uint64_t kDoAddMsg = 0x230a3e0;
|
||||
const uint64_t kSendImageMsg = 0x22b77a0;
|
||||
const uint64_t kChatMsgInstanceCounter = 0x1b59670;
|
||||
const uint64_t kSendFileMsg = 0x20cb6f0;
|
||||
const uint64_t kGetAppMsgMgr = 0x1b544a0;
|
||||
const uint64_t kGetContactMgr = 0x1b3ccd0;
|
||||
const uint64_t kGetContactList = 0x219a1c0;
|
||||
|
||||
const uint64_t k_sqlite3_exec = 0x3a59b30;
|
||||
const uint64_t k_sqlite3_prepare = 0x3a617b0;
|
||||
const uint64_t k_sqlite3_open = 0x3a98fa0;
|
||||
const uint64_t k_sqlite3_step = 0x3a1db30;
|
||||
const uint64_t k_sqlite3_column_count = 0x3a1e350;
|
||||
const uint64_t k_sqlite3_column_name = 0x3a1ed50;
|
||||
const uint64_t k_sqlite3_column_type = 0x3a1eba0;
|
||||
const uint64_t k_sqlite3_column_blob = 0x3a1e380;
|
||||
const uint64_t k_sqlite3_column_bytes = 0x3a1e470;
|
||||
const uint64_t k_sqlite3_finalize = 0x3a1cbe0;
|
||||
|
||||
const uint64_t kGPInstance = 0x58dd300;
|
||||
const uint64_t kMultiDBMgr = 0x593abf8;
|
||||
const uint64_t kPublicMsgMgr = 0x5938198;
|
||||
const uint64_t kFavoriteStorageMgr = 0x593b790;
|
||||
const uint64_t kHardLinkMgr = 0x593ab28;
|
||||
|
||||
const uint64_t kChatRoomMgr = 0x1b7f100;
|
||||
const uint64_t kGetChatRoomDetailInfo = 0x2160bb0;
|
||||
const uint64_t kNewChatRoomInfo = 0x2505120;
|
||||
const uint64_t kFreeChatRoomInfo = 0x2505300;
|
||||
const uint64_t kDoAddMemberToChatRoom = 0x21505b0;
|
||||
const uint64_t kDoModChatRoomMemberNickName = 0x215a360;
|
||||
const uint64_t kDelMemberFromChatRoom = 0x2150bf0;
|
||||
const uint64_t kGetMemberFromChatRoom = 0x2162400;
|
||||
const uint64_t kNewChatRoom = 0x2502540;
|
||||
const uint64_t kFreeChatRoom = 0x2502740;
|
||||
|
||||
const uint64_t kTopMsg = 0x1d7d160;
|
||||
const uint64_t kRemoveTopMsg = 0x2166090;
|
||||
const uint64_t kInviteMember = 0x214ff90;
|
||||
const uint64_t kHookLog = 0x1304e60;
|
||||
|
||||
const uint64_t kCreateChatRoom = 0x214fc60;
|
||||
const uint64_t kQuitChatRoom = 0x215ac00;
|
||||
const uint64_t kForwardMsg = 0x22c1590;
|
||||
|
||||
const uint64_t kOnSnsTimeLineSceneFinish = 0x1a73150;
|
||||
const uint64_t kSNSGetFirstPage = 0x2e1bec0;
|
||||
const uint64_t kSNSGetNextPageScene = 0x2e41a70;
|
||||
const uint64_t kSNSDataMgr = 0x21dd6b0;
|
||||
const uint64_t kSNSTimeLineMgr = 0x2dadf20;
|
||||
const uint64_t kGetMgrByPrefixLocalId = 0x213afb0;
|
||||
const uint64_t kAddFavFromMsg = 0x2930e40;
|
||||
const uint64_t kGetChatMgr = 0x1b82bf0;
|
||||
const uint64_t kGetFavoriteMgr = 0x1b57ba0;
|
||||
const uint64_t kAddFavFromImage = 0x293d0f0;
|
||||
const uint64_t kGetContact = 0x21945d0;
|
||||
const uint64_t kNewContact = 0x2519300;
|
||||
const uint64_t kFreeContact = 0x25199b0;
|
||||
const uint64_t kNewMMReaderItem = 0x8c79a0;
|
||||
const uint64_t kFreeMMReaderItem = 0x8c6da0;
|
||||
const uint64_t kForwordPublicMsg = 0xddc6c0;
|
||||
const uint64_t kParseAppMsgXml = 0x11b0a70;
|
||||
const uint64_t kNewAppMsgInfo = 0x91a550;
|
||||
const uint64_t kFreeAppMsgInfo = 0x8fd1a0;
|
||||
const uint64_t kGetPreDownLoadMgr = 0x1c0a3a0;
|
||||
const uint64_t kPushAttachTask = 0x1cda920;
|
||||
const uint64_t kGetCustomSmileyMgr = 0x1ca0320;
|
||||
const uint64_t kSendCustomEmotion = 0x21b04c0;
|
||||
const uint64_t kNewJsApiShareAppMessage = 0x26cda20;
|
||||
const uint64_t kInitJsConfig = 0x137bc00;
|
||||
const uint64_t kSendApplet = 0x13c0920;
|
||||
const uint64_t kSendAppletSecond = 0x13c1150;
|
||||
const uint64_t kGetAppInfoByWaid = 0x13c5790;
|
||||
const uint64_t kCopyShareAppMessageRequest = 0x13c0670;
|
||||
const uint64_t kNewWAUpdatableMsgInfo = 0x919ca0;
|
||||
const uint64_t kFreeWAUpdatableMsgInfo = 0x8fc230;
|
||||
const uint64_t kSendPatMsg = 0x2ca9790;
|
||||
const uint64_t kGetOCRManager = 0x999780;
|
||||
const uint64_t kDoOCRTask = 0x2c53910;
|
||||
|
||||
const uint64_t kGetLockWechatMgr = 0x1c85010;
|
||||
const uint64_t kRequestLockWechat = 0x1c397d0;
|
||||
const uint64_t kRequestUnLockWechat = 0x1c39a70;
|
||||
|
||||
const uint64_t kOnLoginBtnClick = 0x202bc30;
|
||||
|
||||
const uint64_t kGetQRCodeLoginMgr = 0x201e350;
|
||||
|
||||
const uint64_t kUpdateMsg = 0x21421a0;
|
||||
const uint64_t kGetVoiceMgr = 0x1e13320;
|
||||
const uint64_t kChatMsg2NetSceneSendMsg = 0x1b70fd0;
|
||||
const uint64_t kTranslateVoice = 0x2353d50;
|
||||
const uint64_t kNewWebViewPageConfig = 0x1b53ae0;
|
||||
const uint64_t kFreeWebViewPageConfig = 0x1b53d10;
|
||||
const uint64_t kGetWebViewMgr = 0x1b43950;
|
||||
const uint64_t kShowWebView = 0x302ed30;
|
||||
const uint64_t kSetUrl = 0x13dd410;
|
||||
|
||||
const uint64_t kNewPayInfo = 0x1bcd930;
|
||||
const uint64_t kFreePayInfo = 0x1b92450;
|
||||
const uint64_t kTransferConfirm = 0x2f8c750;
|
||||
const uint64_t kTransferRefuse = 0x2f8d340;
|
||||
|
||||
const uint64_t kAddFriend = 0x1f3a350;
|
||||
const uint64_t kVerifyApply = 0x1f3a940;
|
||||
const uint64_t kDoDelContact = 0x2310120;
|
||||
|
||||
const uint64_t kGetSearchContactMgr = 0x1f9a730;
|
||||
const uint64_t kStartSearch = 0x22a4200;
|
||||
#else
|
||||
|
||||
+344
-436
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -0,0 +1,301 @@
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.collections4.BidiMap;
|
||||
import org.apache.commons.collections4.bidimap.DualHashBidiMap;
|
||||
import docking.widgets.filter.ContainsTextFilterFactory;
|
||||
import docking.widgets.filter.TextFilter;
|
||||
import docking.widgets.filter.TextFilterFactory;
|
||||
import edu.uci.ics.jung.graph.Graph;
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.feature.fid.db.FidFile;
|
||||
import ghidra.feature.fid.db.FidFileManager;
|
||||
import ghidra.graph.GDirectedGraph;
|
||||
import ghidra.graph.GEdge;
|
||||
import ghidra.graph.jung.JungDirectedGraph;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressIterator;
|
||||
import ghidra.program.model.address.AddressSetView;
|
||||
import ghidra.program.model.block.BasicBlockModel;
|
||||
import ghidra.program.model.block.CodeBlock;
|
||||
import ghidra.program.model.block.CodeBlockIterator;
|
||||
import ghidra.program.model.block.CodeBlockModel;
|
||||
import ghidra.program.model.block.CodeBlockReference;
|
||||
import ghidra.program.model.block.CodeBlockReferenceIterator;
|
||||
import ghidra.program.model.block.graph.CodeBlockVertex;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.model.listing.FunctionManager;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.symbol.FlowType;
|
||||
import ghidra.program.model.symbol.Reference;
|
||||
import ghidra.program.model.symbol.ReferenceIterator;
|
||||
import ghidra.program.model.symbol.ReferenceManager;
|
||||
import ghidra.program.model.symbol.Symbol;
|
||||
import ghidra.program.model.symbol.SymbolIterator;
|
||||
import ghidra.program.model.symbol.SymbolTable;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
public class FindCallScript extends GhidraScript {
|
||||
|
||||
@Override
|
||||
protected void run() throws Exception {
|
||||
ContainsTextFilterFactory factory = new ContainsTextFilterFactory(false, true);
|
||||
|
||||
find_send_msg(factory);
|
||||
findFunction(factory,"SendMessageMgr::sendMsg");
|
||||
findFunction(factory,"AppMsgMgr::sendFile");
|
||||
findFunction(factory,"SendMessageMgr::sendImageMsg");
|
||||
findFunction(factory,"SyncMgr::doAddMsg");
|
||||
findFunction(factory,"ChatRoomMgr::doModChatRoomMemberNickName");
|
||||
|
||||
findFunction2(factory,"New_ChatMsg");
|
||||
findFunction2(factory,"Free_ChatMsg");
|
||||
findFunction2(factory,"New_ChatRoomInfo");
|
||||
findFunction2(factory,"Free_ChatRoomInfo");
|
||||
findFunction2(factory,"New_ChatRoom");
|
||||
findFunction2(factory,"Free_ChatRoom");
|
||||
findFunction2(factory,"New_Contact");
|
||||
findFunction2(factory,"Free_Contact");
|
||||
findFunction2(factory,"New_WAUpdatableMsgInfo");
|
||||
findFunction2(factory,"Free_WAUpdatableMsgInfo");
|
||||
findFunction2(factory,"New_AppMsgInfo");
|
||||
findFunction2(factory,"Free_AppMsgInfo");
|
||||
findFunction2(factory,"New_MMReaderItem");
|
||||
findFunction2(factory,"Free_MMReaderItem");
|
||||
findFunction2(factory,"New_WCPayInfo");
|
||||
findFunction2(factory,"Free_WCPayInfo");
|
||||
findFunction2(factory,"New_WebViewPageConfig");
|
||||
findFunction2(factory,"Free_WebViewPageConfig");
|
||||
|
||||
findMgr(factory, "SendMessageMgr::SendMessageMgr", "GetSendMessageMgr");
|
||||
findMgr(factory, "AccountServiceMgr::AccountServiceMgr", "GetAccountServiceMgr");
|
||||
findMgr(factory, "AppMsgMgr::AppMsgMgr", "GetAppMsgMgr");
|
||||
findMgr(factory, "ContactMgr::ContactMgr", "GetContactMgr");
|
||||
findMgr(factory, "ChatRoomMgr::ChatRoomMgr", "GetChatRoomMgr");
|
||||
findMgr(factory, "SNSDataMgr::SNSDataMgr", "GetSNSDataMgr");
|
||||
findMgr(factory, "SNSTimeLineMgr::SNSTimeLineMgr", "GetSNSTimeLineMgr");
|
||||
findMgr(factory, "ChatMgr::ChatMgr", "GetChatMgr");
|
||||
findMgr(factory, "FavoriteMgr::FavoriteMgr", "GetFavoriteMgr");
|
||||
findMgr(factory, "PreDownLoadMgr::PreDownLoadMgr", "GetPreDownLoadMgr");
|
||||
findMgr(factory, "CustomSmileyMgr::CustomSmileyMgr", "GetCustomSmileyMgr");
|
||||
findMgr(factory, "LockWechatMgr::LockWechatMgr", "GetLockWechatMgr");
|
||||
findMgr(factory, "QRCodeLoginMgr::QRCodeLoginMgr", "GetQRCodeLoginMgr");
|
||||
findMgr(factory, "VoiceMgr::VoiceMgr", "GetVoiceMgr");
|
||||
findMgr(factory, "WebViewMgr::WebViewMgr", "GetWebViewMgr");
|
||||
findMgr(factory, "SearchContactMgr::SearchContactMgr", "GetSearchContactMgr");
|
||||
findMgr(factory, "PublicMsgMgr::PublicMsgMgr", "GetPublicMsgMgr");
|
||||
findMgr(factory, "MultiDBMsgMgr::MultiDBMsgMgr", "GetMultiDBMsgMgr");
|
||||
findMgr(factory, "FavoriteStorageMgr::FavoriteStorageMgr", "GetFavoriteStorageMgr");
|
||||
findMgr(factory, "HardLinkMgr::HardLinkMgr", "GetHardLinkMgr");
|
||||
|
||||
}
|
||||
|
||||
private boolean checkFidFile() {
|
||||
FidFileManager fidFileManager = FidFileManager.getInstance();
|
||||
List<FidFile> userFid = fidFileManager.getFidFiles();
|
||||
if (userFid.isEmpty()) {
|
||||
printerr("please import 3.9.11.25.fid fid file.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void find_send_msg(ContainsTextFilterFactory factory) {
|
||||
SymbolTable symbolTable = currentProgram.getSymbolTable();
|
||||
List<Symbol> searchSymbol = searchSymbol(symbolTable, "SendMessageMgr::sendMsg", factory,
|
||||
"SendMessageMgr::sendMsg");
|
||||
for (Symbol symbol : searchSymbol) {
|
||||
println("const uint64_t kSendTextMsg = " + symbol.getAddress().toString());
|
||||
}
|
||||
}
|
||||
|
||||
void findFunction(ContainsTextFilterFactory factory, String functionName) {
|
||||
assertNotNull(factory);
|
||||
assertNotNull(functionName);
|
||||
String name = "";
|
||||
String[] split = functionName.split("::");
|
||||
if (split.length > 1) {
|
||||
name = split[1];
|
||||
char upperCase = Character.toUpperCase(split[1].charAt(0));
|
||||
name = upperCase + split[1].substring(1);
|
||||
} else {
|
||||
char upperCase = Character.toUpperCase(functionName.charAt(0));
|
||||
name = upperCase + functionName.substring(1);
|
||||
}
|
||||
SymbolTable symbolTable = currentProgram.getSymbolTable();
|
||||
List<Symbol> searchSymbol = searchSymbol(symbolTable, functionName, factory, functionName);
|
||||
for (Symbol symbol : searchSymbol) {
|
||||
println("const uint64_t k" + name + " = " + symbol.getAddress().toString());
|
||||
}
|
||||
}
|
||||
|
||||
void findFunction2(ContainsTextFilterFactory factory, String functionName) {
|
||||
assertNotNull(factory);
|
||||
assertNotNull(functionName);
|
||||
String name = "";
|
||||
String split = functionName.replace("_", "");
|
||||
char upperCase = Character.toUpperCase(split.charAt(0));
|
||||
name = upperCase + split.substring(1);
|
||||
SymbolTable symbolTable = currentProgram.getSymbolTable();
|
||||
List<Symbol> searchSymbol = searchSymbol(symbolTable, functionName, factory, functionName);
|
||||
for (Symbol symbol : searchSymbol) {
|
||||
println("const uint64_t k" + name + " = " + symbol.getAddress().toString());
|
||||
}
|
||||
}
|
||||
|
||||
void find_Mgr(ContainsTextFilterFactory factory) throws CancelledException {
|
||||
if (!checkFidFile()) {
|
||||
return;
|
||||
}
|
||||
SymbolTable symbolTable = currentProgram.getSymbolTable();
|
||||
FunctionManager functionManager = currentProgram.getFunctionManager();
|
||||
ReferenceManager referenceManager = currentProgram.getReferenceManager();
|
||||
|
||||
List<Address> addresses = new ArrayList<>();
|
||||
List<Symbol> searchMgr = searchSymbol(symbolTable, "SendMessageMgr::SendMessageMgr", factory,
|
||||
"SendMessageMgr::SendMessageMgr");
|
||||
for (Symbol symbol : searchMgr) {
|
||||
Address address = symbol.getAddress();
|
||||
ReferenceIterator referencesTo = referenceManager.getReferencesTo(address);
|
||||
while (referencesTo.hasNext()) {
|
||||
Reference next = referencesTo.next();
|
||||
Address fromAddress = next.getFromAddress();
|
||||
println("fromAddress " + fromAddress.toString());
|
||||
Function functionAt = functionManager.getFunctionContaining(fromAddress);
|
||||
if (null != functionAt) {
|
||||
addresses.add(functionAt.getEntryPoint());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<Symbol> searchSymbol = searchSymbol(symbolTable, "GetSendMessageMgr", factory, "GetSendMessageMgr");
|
||||
for (Symbol symbol : searchSymbol) {
|
||||
Address address = symbol.getAddress();
|
||||
if (addresses.contains(address)) {
|
||||
println("const uint64_t kGetSendMessageMgr = " + address.toString() + ";");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void find_SendMessageMgr(ContainsTextFilterFactory factory) throws CancelledException {
|
||||
if (!checkFidFile()) {
|
||||
return;
|
||||
}
|
||||
SymbolTable symbolTable = currentProgram.getSymbolTable();
|
||||
FunctionManager functionManager = currentProgram.getFunctionManager();
|
||||
|
||||
List<Address> addresses = new ArrayList<>();
|
||||
List<Symbol> searchMgr = searchSymbol(symbolTable, "SendMessageMgr::SendMessageMgr", factory,
|
||||
"SendMessageMgr::SendMessageMgr");
|
||||
for (Symbol symbol : searchMgr) {
|
||||
Address address = symbol.getAddress();
|
||||
addresses.add(address);
|
||||
}
|
||||
|
||||
List<Symbol> searchSymbol = searchSymbol(symbolTable, "GetSendMessageMgr", factory, "GetSendMessageMgr");
|
||||
for (Symbol symbol : searchSymbol) {
|
||||
Address address = symbol.getAddress();
|
||||
Function function = functionManager.getFunctionAt(address);
|
||||
if (null != function) {
|
||||
AddressSetView functionBody = function.getBody();
|
||||
Address entryPoint = function.getEntryPoint();
|
||||
Set<Reference> references = getReferencesFrom(currentProgram, functionBody, monitor);
|
||||
for (Reference reference : references) {
|
||||
monitor.checkCancelled();
|
||||
Address toAddress = reference.getToAddress();
|
||||
if (toAddress.equals(entryPoint)) {
|
||||
continue;
|
||||
}
|
||||
Function calledFunction = functionManager.getFunctionAt(toAddress);
|
||||
if (null != calledFunction) {
|
||||
if (addresses.contains(toAddress)) {
|
||||
println("const uint64_t kGetSendMessageMgr = " + address.toString() + ";");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void findMgr(ContainsTextFilterFactory factory, String mgr, String getMgr) throws CancelledException {
|
||||
if (!checkFidFile()) {
|
||||
return;
|
||||
}
|
||||
SymbolTable symbolTable = currentProgram.getSymbolTable();
|
||||
FunctionManager functionManager = currentProgram.getFunctionManager();
|
||||
|
||||
List<Address> addresses = new ArrayList<>();
|
||||
List<Symbol> searchMgr = searchSymbol(symbolTable, mgr, factory, mgr);
|
||||
for (Symbol symbol : searchMgr) {
|
||||
Address address = symbol.getAddress();
|
||||
addresses.add(address);
|
||||
}
|
||||
|
||||
List<Symbol> searchSymbol = searchSymbol(symbolTable, getMgr, factory, getMgr);
|
||||
for (Symbol symbol : searchSymbol) {
|
||||
Address address = symbol.getAddress();
|
||||
Function function = functionManager.getFunctionAt(address);
|
||||
if (null != function) {
|
||||
AddressSetView functionBody = function.getBody();
|
||||
Address entryPoint = function.getEntryPoint();
|
||||
Set<Reference> references = getReferencesFrom(currentProgram, functionBody, monitor);
|
||||
for (Reference reference : references) {
|
||||
monitor.checkCancelled();
|
||||
Address toAddress = reference.getToAddress();
|
||||
if (toAddress.equals(entryPoint)) {
|
||||
continue;
|
||||
}
|
||||
Function calledFunction = functionManager.getFunctionAt(toAddress);
|
||||
if (null != calledFunction) {
|
||||
if (addresses.contains(toAddress)) {
|
||||
println("const uint64_t k" + getMgr + " = " + address.toString() + " ;");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected Set<Reference> getReferencesFrom(Program program, AddressSetView addresses, TaskMonitor monitor)
|
||||
throws CancelledException {
|
||||
Set<Reference> set = new HashSet<>();
|
||||
ReferenceManager referenceManager = program.getReferenceManager();
|
||||
AddressIterator addressIterator = addresses.getAddresses(true);
|
||||
while (addressIterator.hasNext()) {
|
||||
monitor.checkCancelled();
|
||||
Address address = addressIterator.next();
|
||||
Reference[] referencesFrom = referenceManager.getReferencesFrom(address);
|
||||
if (referencesFrom != null) {
|
||||
for (Reference reference : referencesFrom) {
|
||||
set.add(reference);
|
||||
}
|
||||
}
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
List<Symbol> searchSymbol(SymbolTable symbolTable, String text, TextFilterFactory factory, String filterText) {
|
||||
List<Symbol> list = new ArrayList<>();
|
||||
TextFilter textFilter = factory.getTextFilter(filterText);
|
||||
SymbolIterator symbols = symbolTable.getSymbols(text);
|
||||
while (symbols.hasNext()) {
|
||||
Symbol next = symbols.next();
|
||||
if (textFilter.matches(next.getName())) {
|
||||
list.add(next);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,386 @@
|
||||
// find mars
|
||||
//@author ttttupup
|
||||
//@category _NEW_
|
||||
//@keybinding
|
||||
//@menupath
|
||||
//@toolbar
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import docking.widgets.filter.ContainsTextFilterFactory;
|
||||
import docking.widgets.filter.TextFilter;
|
||||
import ghidra.app.decompiler.DecompInterface;
|
||||
import ghidra.app.decompiler.DecompileOptions;
|
||||
import ghidra.app.decompiler.DecompileResults;
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressFactory;
|
||||
import ghidra.program.model.address.AddressIterator;
|
||||
import ghidra.program.model.address.AddressSet;
|
||||
import ghidra.program.model.address.AddressSetView;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.program.model.block.BasicBlockModel;
|
||||
import ghidra.program.model.block.CodeBlock;
|
||||
import ghidra.program.model.listing.CodeUnit;
|
||||
import ghidra.program.model.listing.Data;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.model.listing.FunctionManager;
|
||||
import ghidra.program.model.listing.Instruction;
|
||||
import ghidra.program.model.mem.MemoryAccessException;
|
||||
import ghidra.program.model.pcode.HighFunction;
|
||||
import ghidra.program.model.pcode.PcodeBlockBasic;
|
||||
import ghidra.program.model.pcode.PcodeOp;
|
||||
import ghidra.program.model.pcode.PcodeOpAST;
|
||||
import ghidra.program.model.pcode.Varnode;
|
||||
import ghidra.program.model.symbol.Reference;
|
||||
import ghidra.program.model.symbol.ReferenceIterator;
|
||||
import ghidra.program.model.symbol.ReferenceManager;
|
||||
import ghidra.program.model.symbol.SourceType;
|
||||
import ghidra.program.util.string.FoundString;
|
||||
import ghidra.sleigh.grammar.SleighParser.stringorident_return;
|
||||
import ghidra.util.StringUtilities;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
import ghidra.util.exception.InvalidInputException;
|
||||
|
||||
public class FindMarsScript extends GhidraScript {
|
||||
DecompInterface decompiler = new DecompInterface();
|
||||
BasicBlockModel basicBlockModel;
|
||||
|
||||
@Override
|
||||
protected void run() throws Exception {
|
||||
DecompileOptions decompileOptions = new DecompileOptions();
|
||||
decompiler.setOptions(decompileOptions);
|
||||
decompiler.openProgram(currentProgram);
|
||||
basicBlockModel = new BasicBlockModel(currentProgram);
|
||||
Address findXScopeTracer = findXScopeTracer();
|
||||
// Address findXScopeTracer = currentProgram.getAddressFactory().getAddress("0x183d04d10");
|
||||
if (null != findXScopeTracer) {
|
||||
ReferenceIterator referenceIterator = currentProgram.getReferenceManager()
|
||||
.getReferencesTo(findXScopeTracer);
|
||||
while (referenceIterator.hasNext()) {
|
||||
monitor.checkCancelled();
|
||||
Reference next = referenceIterator.next();
|
||||
Address fromAddress = next.getFromAddress();
|
||||
|
||||
Function functionContaining = currentProgram.getFunctionManager().getFunctionContaining(fromAddress);
|
||||
if (null == functionContaining) {
|
||||
println("no found function: " + fromAddress.toString());
|
||||
continue;
|
||||
}
|
||||
DecompileResults res = decompiler.decompileFunction(functionContaining, 20, null);
|
||||
if (!res.decompileCompleted()) {
|
||||
println("decompile error: " + res.getErrorMessage());
|
||||
continue;
|
||||
}
|
||||
HighFunction highFunction = res.getHighFunction();
|
||||
Iterator<PcodeOpAST> pcodeOps = highFunction.getPcodeOps();
|
||||
while (pcodeOps.hasNext()) {
|
||||
monitor.checkCancelled();
|
||||
PcodeOpAST opAST = pcodeOps.next();
|
||||
int opcode = opAST.getOpcode();
|
||||
if (PcodeOp.CALL == opcode || PcodeOp.CALLIND == opcode || PcodeOp.CALLOTHER == opcode) {
|
||||
Varnode input0 = opAST.getInput(0);
|
||||
boolean contains = input0.contains(findXScopeTracer);
|
||||
|
||||
if (contains) {
|
||||
Varnode input3 = opAST.getInput(3);
|
||||
Varnode input4 = opAST.getInput(4);
|
||||
if (input4 == null || input3 == null) {
|
||||
continue;
|
||||
}
|
||||
String namespaceString = "";
|
||||
String funcNameString = "";
|
||||
if (input3.isUnique()) {
|
||||
namespaceString = getUniqueValue(input3);
|
||||
} else if (input3.isConstant()) {
|
||||
namespaceString = getConstact(input3);
|
||||
}
|
||||
if (input4.isUnique()) {
|
||||
funcNameString = getUniqueValue(input4);
|
||||
} else if (input4.isConstant()) {
|
||||
funcNameString = getConstact(input4);
|
||||
}
|
||||
if (StringUtilities.isAllBlank(namespaceString)
|
||||
|| StringUtilities.isAllBlank(funcNameString)) {
|
||||
continue;
|
||||
}
|
||||
String name = namespaceString.replace(" ", "") + "::" + funcNameString.replace(" ", "");
|
||||
println("find function :" + name);
|
||||
functionContaining.setName(name, SourceType.USER_DEFINED);
|
||||
currentProgram.getListing().setComment(functionContaining.getEntryPoint(),
|
||||
CodeUnit.EOL_COMMENT, "mars scipt auto define: " + name);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String getConstact(Varnode input3) {
|
||||
Address address2 = input3.getAddress();
|
||||
Address address3 = currentProgram.getAddressFactory().getDefaultAddressSpace().getAddress(address2.getOffset());
|
||||
Data dataAt2 = getDataAt(address3);
|
||||
if (null != dataAt2) {
|
||||
if (dataAt2.hasStringValue()) {
|
||||
return dataAt2.getValue().toString();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void easy(Address findXScopeTracer) throws CancelledException {
|
||||
if (null != findXScopeTracer) {
|
||||
ReferenceIterator referenceIterator = currentProgram.getReferenceManager()
|
||||
.getReferencesTo(findXScopeTracer);
|
||||
while (referenceIterator.hasNext()) {
|
||||
monitor.checkCancelled();
|
||||
Reference next = referenceIterator.next();
|
||||
Address fromAddress = next.getFromAddress();
|
||||
Instruction instructionAt = currentProgram.getListing().getInstructionAt(fromAddress);
|
||||
if (null != instructionAt) {
|
||||
PcodeOp[] pcode = instructionAt.getPcode();
|
||||
if (null != pcode) {
|
||||
for (PcodeOp pcodeOp : pcode) {
|
||||
if (pcodeOp.getOpcode() == PcodeOp.CALL) {
|
||||
Varnode namespace = pcodeOp.getInput(3);
|
||||
Varnode funcName = pcodeOp.getInput(4);
|
||||
if (null != namespace) {
|
||||
if (namespace.isConstant()) {
|
||||
long offset = namespace.getAddress().getOffset();
|
||||
Address address = currentProgram.getAddressFactory().getDefaultAddressSpace()
|
||||
.getAddress(offset);
|
||||
Data dataAt = currentProgram.getListing().getDataAt(address);
|
||||
if (null != dataAt) {
|
||||
if (dataAt.hasStringValue()) {
|
||||
dataAt.getValue().toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (null != funcName) {
|
||||
if (funcName.isConstant()) {
|
||||
long offset = funcName.getAddress().getOffset();
|
||||
Address address = currentProgram.getAddressFactory().getDefaultAddressSpace()
|
||||
.getAddress(offset);
|
||||
Data dataAt = currentProgram.getListing().getDataAt(address);
|
||||
if (null != dataAt) {
|
||||
if (dataAt.hasStringValue()) {
|
||||
dataAt.getValue().toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println("caller address: " + fromAddress.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void find() throws Exception {
|
||||
Function findXLogger = findXLogger();
|
||||
if (null != findXLogger) {
|
||||
if (findXLogger.isThunk()) {
|
||||
currentProgram.getFunctionManager().createFunction("XLogger::operator()", findXLogger.getEntryPoint(),
|
||||
findXLogger.getBody(), findXLogger.getSignatureSource());
|
||||
} else {
|
||||
|
||||
findXLogger.setName("XLogger::operator()", SourceType.USER_DEFINED);
|
||||
currentProgram.getListing().setComment(findXLogger.getEntryPoint(), CodeUnit.EOL_COMMENT,
|
||||
"rename function: XLogger::operator()");
|
||||
|
||||
ReferenceIterator referenceIterator = currentProgram.getReferenceManager()
|
||||
.getReferencesTo(findXLogger.getEntryPoint());
|
||||
while (referenceIterator.hasNext()) {
|
||||
monitor.checkCancelled();
|
||||
Reference next = referenceIterator.next();
|
||||
Address fromAddress = next.getFromAddress();
|
||||
println("caller address: " + fromAddress.toString());
|
||||
handle(fromAddress, findXLogger.getEntryPoint());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Address findXScopeTracer() throws Exception {
|
||||
List<FoundString> list = findStrings(null, 5, 1, true, false);
|
||||
ContainsTextFilterFactory factory = new ContainsTextFilterFactory(false, true);
|
||||
TextFilter textFilter = factory.getTextFilter("mars::comm::DNS::GetHostByName");
|
||||
for (FoundString foundString : list) {
|
||||
monitor.checkCancelled();
|
||||
String string = foundString.getString(currentProgram.getMemory());
|
||||
if (textFilter.matches(string)) {
|
||||
Address address = foundString.getAddress();
|
||||
println("=====text addr :" + address.toString());
|
||||
|
||||
ReferenceIterator referencesTo = currentProgram.getReferenceManager().getReferencesTo(address);
|
||||
while (referencesTo.hasNext()) {
|
||||
Reference ref = referencesTo.next();
|
||||
Address textAddress = ref.getFromAddress();
|
||||
Function func = currentProgram.getFunctionManager().getFunctionContaining(textAddress);
|
||||
if (null == func) {
|
||||
continue;
|
||||
}
|
||||
CodeBlock[] codeBlocksContaining = basicBlockModel.getCodeBlocksContaining(textAddress, monitor);
|
||||
for (CodeBlock codeBlock : codeBlocksContaining) {
|
||||
AddressIterator addressIterator = codeBlock.getAddresses(true);
|
||||
while (addressIterator.hasNext()) {
|
||||
Address next = addressIterator.next();
|
||||
CodeUnit codeUnitAt = currentProgram.getListing().getCodeUnitAt(next);
|
||||
if (null != codeUnitAt) {
|
||||
if (codeUnitAt.getMnemonicString().equals("CALL")) {
|
||||
Instruction instructionAt = currentProgram.getListing().getInstructionAt(next);
|
||||
PcodeOp[] pcode = instructionAt.getPcode();
|
||||
PcodeOp pcodeOp = pcode[pcode.length - 1];
|
||||
Varnode input = pcodeOp.getInput(0);
|
||||
Address address2 = input.getAddress();
|
||||
println("===== XScopeTracer::XScopeTracer addr :" + address2.toString());
|
||||
Function functionAt = currentProgram.getFunctionManager().getFunctionAt(address2);
|
||||
if (null != functionAt) {
|
||||
functionAt.setName("XScopeTracer::XScopeTracer", SourceType.USER_DEFINED);
|
||||
currentProgram.getListing().setComment(functionAt.getEntryPoint(),
|
||||
CodeUnit.EOL_COMMENT, "scipt auto define: XScopeTracer::XScopeTracer");
|
||||
} else {
|
||||
createFunction(address2, "XScopeTracer::XScopeTracer");
|
||||
currentProgram.getListing().setComment(address2, CodeUnit.EOL_COMMENT,
|
||||
"scipt auto create: XScopeTracer::XScopeTracer");
|
||||
}
|
||||
|
||||
return address2;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
private void handle(Address address, Address calleeAddress) throws CancelledException {
|
||||
Function functionContaining = currentProgram.getFunctionManager().getFunctionContaining(address);
|
||||
if (null == functionContaining) {
|
||||
println("no found function: " + address.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
DecompileResults res = decompiler.decompileFunction(functionContaining, 20, null);
|
||||
if (!res.decompileCompleted()) {
|
||||
println("decompile error: " + res.getErrorMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
HighFunction highFunction = res.getHighFunction();
|
||||
ArrayList<PcodeBlockBasic> basicBlocks = highFunction.getBasicBlocks();
|
||||
|
||||
for (PcodeBlockBasic pcodeBlockBasic : basicBlocks) {
|
||||
monitor.checkCancelled();
|
||||
boolean contains = pcodeBlockBasic.contains(address);
|
||||
if (contains) {
|
||||
Iterator<PcodeOp> iterator = pcodeBlockBasic.getIterator();
|
||||
for (; iterator.hasNext();) {
|
||||
monitor.checkCancelled();
|
||||
PcodeOp next = iterator.next();
|
||||
if (next.getOpcode() == PcodeOp.CALL) {
|
||||
if (next.getNumInputs() > 4) {
|
||||
Varnode input3 = next.getInput(3);
|
||||
if (null != input3) {
|
||||
if (input3.isUnique()) {
|
||||
String uniqueValue = getUniqueValue(input3);
|
||||
if (null != uniqueValue) {
|
||||
println(uniqueValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String getUniqueValue(Varnode input3) {
|
||||
PcodeOp def = input3.getDef();
|
||||
Varnode[] inputs = def.getInputs();
|
||||
if (null != inputs && inputs.length > 0) {
|
||||
if (inputs[0].isConstant()) {
|
||||
Address address2 = inputs[0].getAddress();
|
||||
Address address3 = currentProgram.getAddressFactory().getDefaultAddressSpace()
|
||||
.getAddress(address2.getOffset());
|
||||
Data dataAt2 = currentProgram.getListing().getDataAt(address3);
|
||||
if (null != dataAt2) {
|
||||
if (dataAt2.hasStringValue()) {
|
||||
return dataAt2.getValue().toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Function findXLogger() throws MemoryAccessException, CancelledException {
|
||||
|
||||
FunctionManager functionManager = currentProgram.getFunctionManager();
|
||||
ReferenceManager referenceManager = currentProgram.getReferenceManager();
|
||||
AddressFactory factory = currentProgram.getAddressFactory();
|
||||
AddressSpace[] addressSpaces = factory.getAddressSpaces();
|
||||
AddressSetView initializedMemory = currentProgram.getMemory().getLoadedAndInitializedAddressSet();
|
||||
|
||||
AddressSet searchSet = initializedMemory.intersect(new AddressSet(initializedMemory));
|
||||
List<FoundString> findStrings = new ArrayList<>();
|
||||
println("初次查询速度较慢,请耐心等待。");
|
||||
for (AddressSpace space : addressSpaces) {
|
||||
if (monitor.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
AddressSet intersecting = searchSet.intersectRange(space.getMinAddress(), space.getMaxAddress());
|
||||
findStrings.addAll(findStrings(null, 10, 1, true, true));
|
||||
}
|
||||
|
||||
if (null != findStrings && findStrings.size() > 0) {
|
||||
ContainsTextFilterFactory containsTextFilterFactory = new ContainsTextFilterFactory(false, true);
|
||||
TextFilter textFilter = containsTextFilterFactory
|
||||
.getTextFilter("XLogger& XLogger::operator()(const char* _format, ...)");
|
||||
for (FoundString foundString : findStrings) {
|
||||
if (monitor.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
String string = foundString.getString(currentProgram.getMemory());
|
||||
if (textFilter.matches(string)) {
|
||||
Address address = foundString.getAddress();
|
||||
println(address.toString());
|
||||
|
||||
ReferenceIterator referencesTo = referenceManager.getReferencesTo(address);
|
||||
while (referencesTo.hasNext()) {
|
||||
if (monitor.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
Reference ref = referencesTo.next();
|
||||
Address xLoggerAddr = ref.getFromAddress();
|
||||
Function targetFunction = functionManager.getFunctionContaining(xLoggerAddr);
|
||||
if (null == targetFunction) {
|
||||
continue;
|
||||
}
|
||||
println("XLogger::operator() :" + targetFunction.getEntryPoint().toString());
|
||||
return targetFunction;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
import java.util.List;
|
||||
|
||||
import docking.widgets.filter.ContainsTextFilterFactory;
|
||||
import docking.widgets.filter.TextFilter;
|
||||
import ghidra.app.decompiler.DecompInterface;
|
||||
import ghidra.app.decompiler.DecompileOptions;
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.feature.fid.hash.FidHashQuad;
|
||||
import ghidra.feature.fid.service.FidService;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.listing.CodeUnit;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.model.listing.FunctionManager;
|
||||
import ghidra.program.model.mem.MemoryAccessException;
|
||||
import ghidra.program.model.symbol.Reference;
|
||||
import ghidra.program.model.symbol.ReferenceIterator;
|
||||
import ghidra.program.model.symbol.ReferenceManager;
|
||||
import ghidra.program.util.string.FoundString;
|
||||
import ghidra.util.UndefinedFunction;
|
||||
|
||||
public class FindSqliteCloseScript extends GhidraScript {
|
||||
FidService service;
|
||||
DecompInterface decompiler;
|
||||
|
||||
long sql3close_full_hash = -1574752015815545339L;
|
||||
long sql3close_spec_hash = -1262376715505923342L;
|
||||
|
||||
@Override
|
||||
protected void run() throws Exception {
|
||||
service = new FidService();
|
||||
|
||||
decompiler = new DecompInterface();
|
||||
DecompileOptions decompileOptions = new DecompileOptions();
|
||||
decompiler.setOptions(decompileOptions);
|
||||
decompiler.openProgram(currentProgram);
|
||||
|
||||
List<FoundString> findStrings = findStrings(null, 5, 1, true, false);
|
||||
ContainsTextFilterFactory containsTextFilterFactory = new ContainsTextFilterFactory(false, true);
|
||||
find_sqlite3Close(findStrings,containsTextFilterFactory);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void find_sqlite3Close(List<FoundString> list, ContainsTextFilterFactory factory) throws MemoryAccessException {
|
||||
int size = currentProgram.getLanguage().getLanguageDescription().getSize() / 8;
|
||||
FunctionManager functionManager = currentProgram.getFunctionManager();
|
||||
ReferenceManager referenceManager = currentProgram.getReferenceManager();
|
||||
TextFilter textFilter = factory.getTextFilter("unable to close due to unfinalized statements or unfinished backups");
|
||||
for (FoundString foundString : list) {
|
||||
if(monitor.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
String string = foundString.getString(currentProgram.getMemory());
|
||||
if(textFilter.matches(string)) {
|
||||
Address address = foundString.getAddress();
|
||||
println("=====text addr :"+address.toString() );
|
||||
ReferenceIterator referencesTo = referenceManager.getReferencesTo(address);
|
||||
while (referencesTo.hasNext()) {
|
||||
Reference ref = referencesTo.next();
|
||||
Address sql3CloseAddr = ref.getFromAddress();
|
||||
Function sql3CloseFunction = functionManager.getFunctionContaining(sql3CloseAddr);
|
||||
if(null ==sql3CloseFunction ) {
|
||||
continue;
|
||||
}
|
||||
FidHashQuad hashQuad = service.hashFunction(sql3CloseFunction);
|
||||
if(hashQuad.getFullHash() == sql3close_full_hash && hashQuad.getSpecificHash() == sql3close_spec_hash) {
|
||||
println("found sql3Close :" + sql3CloseFunction.getName() + " at " + sql3CloseFunction.getEntryPoint() +
|
||||
" full hash " + hashQuad.getFullHash() + " specific hash " + hashQuad.getSpecificHash());
|
||||
Address entryPoint = sql3CloseFunction.getEntryPoint();
|
||||
ReferenceIterator referencesTo2 = referenceManager.getReferencesTo(entryPoint);
|
||||
while (referencesTo2.hasNext()) {
|
||||
Reference next = referencesTo2.next();
|
||||
Address addr = next.getFromAddress();
|
||||
Function sql_close_func = functionManager.getFunctionContaining(addr);
|
||||
if(null !=sql_close_func ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
CodeUnit codeUnitAt = currentProgram.getListing().getCodeUnitAt(addr);
|
||||
if(null != codeUnitAt) {
|
||||
String mnemonicString = codeUnitAt.getMnemonicString();
|
||||
if("JMP".equals(mnemonicString)) {
|
||||
CodeUnit codeUnitBefore = currentProgram.getListing().getCodeUnitBefore(addr);
|
||||
String mnemonicString2 = codeUnitBefore.getMnemonicString();
|
||||
Function function = UndefinedFunction.findFunction(currentProgram, addr, monitor);
|
||||
if (null != function) {
|
||||
Address entryPoint2 = function.getEntryPoint();
|
||||
if("XOR".equals(mnemonicString2)) {
|
||||
createFunction(entryPoint2, "sqlite3_close");
|
||||
currentProgram.getListing().setComment(entryPoint2, CodeUnit.POST_COMMENT,
|
||||
"auto define function: sqlite3_close");
|
||||
println("sqlite3_close addr: " + entryPoint2.toString());
|
||||
}else if ("MOV".equals(mnemonicString2)) {
|
||||
createFunction(entryPoint2, "sqlite3_close_v2");
|
||||
currentProgram.getListing().setComment(entryPoint2, CodeUnit.POST_COMMENT,
|
||||
"auto define function : sqlite3_close_v2" );
|
||||
println("sqlite3_close_v2 addr: " + entryPoint2.toString());
|
||||
}
|
||||
ReferenceIterator referencesTo3 = referenceManager.getReferencesTo(entryPoint2);
|
||||
while (referencesTo3.hasNext()) {
|
||||
Reference next2 = referencesTo3.next();
|
||||
Address fromAddress = next2.getFromAddress();
|
||||
if("XOR".equals(mnemonicString2)) {
|
||||
long l = fromAddress.getOffset() - 16*size;
|
||||
println("sqlite3_close xref:" + fromAddress.toString());
|
||||
printf("sqlite3_api_routines addr: %x \n", l);
|
||||
}else if ("MOV".equals(mnemonicString2)) {
|
||||
long l = fromAddress.getOffset()- 179*size;
|
||||
println("sqlite3_close_v2 xref:" +fromAddress.toString());
|
||||
printf("sqlite3_api_routines addr: %x \n", l);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.collections4.BidiMap;
|
||||
import org.apache.commons.collections4.bidimap.DualHashBidiMap;
|
||||
|
||||
import edu.uci.ics.jung.graph.Graph;
|
||||
import generic.stl.Pair;
|
||||
import ghidra.graph.GDirectedGraph;
|
||||
import ghidra.graph.GEdge;
|
||||
import ghidra.graph.jung.JungDirectedGraph;
|
||||
import ghidra.program.model.address.AddressSetView;
|
||||
import ghidra.program.model.block.BasicBlockModel;
|
||||
import ghidra.program.model.block.CodeBlock;
|
||||
import ghidra.program.model.block.CodeBlockIterator;
|
||||
import ghidra.program.model.block.CodeBlockModel;
|
||||
import ghidra.program.model.block.CodeBlockReference;
|
||||
import ghidra.program.model.block.CodeBlockReferenceIterator;
|
||||
import ghidra.program.model.block.graph.CodeBlockVertex;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.symbol.FlowType;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
public class GraphFunctionFactory {
|
||||
|
||||
public static Pair<GDirectedGraph<FunctionVertex, FunctionEdge>, BidiMap<CodeBlock, FunctionVertex>> createGraph(
|
||||
Function f, TaskMonitor monitor) throws CancelledException {
|
||||
if (monitor == null) {
|
||||
monitor = TaskMonitor.DUMMY;
|
||||
}
|
||||
|
||||
JungDirectedGraph<FunctionVertex, FunctionEdge> graph = new JungDirectedGraph<>();
|
||||
|
||||
BidiMap<CodeBlock, FunctionVertex> vertices = createVertices(f, monitor);
|
||||
for (FunctionVertex v : vertices.values()) {
|
||||
graph.addVertex(v);
|
||||
}
|
||||
|
||||
Collection<FunctionEdge> edges = createdEdges(vertices, monitor);
|
||||
for (FunctionEdge e : edges) {
|
||||
graph.addEdge(e);
|
||||
}
|
||||
|
||||
// this must be done after the edges are added to the graph
|
||||
for (FunctionVertex vertex : vertices.values()) {
|
||||
vertex.setType(getVertexType(graph, vertex));
|
||||
}
|
||||
return new Pair<GDirectedGraph<FunctionVertex, FunctionEdge>, BidiMap<CodeBlock, FunctionVertex>>(graph,
|
||||
vertices);
|
||||
}
|
||||
|
||||
private static BidiMap<CodeBlock, FunctionVertex> createVertices(Function f, TaskMonitor monitor)
|
||||
throws CancelledException {
|
||||
|
||||
BidiMap<CodeBlock, FunctionVertex> vertices = new DualHashBidiMap<>();
|
||||
Program p = f.getProgram();
|
||||
CodeBlockModel blockModel = new BasicBlockModel(p);
|
||||
|
||||
AddressSetView addresses = f.getBody();
|
||||
CodeBlockIterator iterator = blockModel.getCodeBlocksContaining(addresses, monitor);
|
||||
monitor.initialize(addresses.getNumAddresses());
|
||||
|
||||
for (; iterator.hasNext();) {
|
||||
CodeBlock codeBlock = iterator.next();
|
||||
|
||||
FlowType flowType = codeBlock.getFlowType();
|
||||
boolean isEntry = isEntry(codeBlock);
|
||||
|
||||
FunctionVertex vertex = new FunctionVertex(codeBlock, flowType, isEntry);
|
||||
|
||||
vertices.put(codeBlock, vertex);
|
||||
|
||||
long blockAddressCount = codeBlock.getNumAddresses();
|
||||
long currentProgress = monitor.getProgress();
|
||||
monitor.setProgress(currentProgress + blockAddressCount);
|
||||
}
|
||||
|
||||
return vertices;
|
||||
}
|
||||
|
||||
private static Collection<FunctionEdge> createdEdges(BidiMap<CodeBlock, FunctionVertex> vertices,
|
||||
TaskMonitor monitor) throws CancelledException {
|
||||
|
||||
List<FunctionEdge> edges = new ArrayList<>();
|
||||
for (FunctionVertex startVertex : vertices.values()) {
|
||||
Collection<FunctionEdge> vertexEdges = getEdgesForStartVertex(vertices, startVertex, monitor);
|
||||
|
||||
edges.addAll(vertexEdges);
|
||||
}
|
||||
|
||||
return edges;
|
||||
}
|
||||
|
||||
private static Collection<FunctionEdge> getEdgesForStartVertex(BidiMap<CodeBlock, FunctionVertex> blockToVertexMap,
|
||||
FunctionVertex startVertex, TaskMonitor monitor) throws CancelledException {
|
||||
|
||||
List<FunctionEdge> edges = new ArrayList<>();
|
||||
CodeBlock codeBlock = blockToVertexMap.getKey(startVertex);
|
||||
CodeBlockReferenceIterator destinations = codeBlock.getDestinations(monitor);
|
||||
for (; destinations.hasNext();) {
|
||||
CodeBlockReference reference = destinations.next();
|
||||
CodeBlock destinationBlock = reference.getDestinationBlock();
|
||||
FunctionVertex destinationVertex = blockToVertexMap.get(destinationBlock);
|
||||
if (destinationVertex == null) {
|
||||
continue;// no vertex means the code block is not in our function
|
||||
}
|
||||
|
||||
edges.add(new FunctionEdge(startVertex, destinationVertex, reference.getFlowType()));
|
||||
}
|
||||
return edges;
|
||||
}
|
||||
|
||||
private static VertexType getVertexType(Graph<FunctionVertex, FunctionEdge> graph, FunctionVertex v) {
|
||||
|
||||
boolean isEntry = v.isEntry();
|
||||
boolean isExit = false;
|
||||
|
||||
FlowType flowType = v.getFlowType();
|
||||
if (flowType.isTerminal()) {
|
||||
isExit = true;
|
||||
}
|
||||
|
||||
Collection<FunctionEdge> outs = graph.getOutEdges(v);
|
||||
if (outs == null || outs.isEmpty()) {
|
||||
isExit = true;
|
||||
}
|
||||
|
||||
VertexType type = VertexType.BODY;
|
||||
if (isEntry) {
|
||||
if (isExit) {
|
||||
type = VertexType.SINGLETON;
|
||||
} else {
|
||||
type = VertexType.ENTRY;
|
||||
}
|
||||
} else if (isExit) {
|
||||
type = VertexType.EXIT;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
private static boolean isEntry(CodeBlock codeBlock) {
|
||||
boolean isSource = true;
|
||||
try {
|
||||
CodeBlockReferenceIterator iter = codeBlock.getSources(TaskMonitor.DUMMY);
|
||||
while (iter.hasNext()) {
|
||||
isSource = false;
|
||||
if (iter.next().getFlowType().isCall()) {
|
||||
// any calls into a code block will make it an 'entry'
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (CancelledException e) {
|
||||
// will never happen, because I don't have a monitor
|
||||
}
|
||||
return isSource;
|
||||
}
|
||||
}
|
||||
|
||||
class FunctionVertex extends CodeBlockVertex {
|
||||
|
||||
private VertexType type = VertexType.BODY;
|
||||
private FlowType flowType;
|
||||
private boolean isEntry;
|
||||
|
||||
public FunctionVertex(CodeBlock codeBlock, FlowType flowType, boolean isEntry) {
|
||||
super(codeBlock);
|
||||
this.flowType = flowType;
|
||||
this.isEntry = isEntry;
|
||||
}
|
||||
|
||||
public boolean isEntry() {
|
||||
return isEntry;
|
||||
}
|
||||
|
||||
public FlowType getFlowType() {
|
||||
return flowType;
|
||||
}
|
||||
|
||||
public VertexType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(VertexType type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
|
||||
class FunctionEdge implements GEdge<FunctionVertex> {
|
||||
|
||||
private FunctionVertex start;
|
||||
private FunctionVertex end;
|
||||
private FlowType flowType;
|
||||
|
||||
public FunctionEdge(FunctionVertex start, FunctionVertex end, FlowType flowType) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.flowType = flowType;
|
||||
}
|
||||
|
||||
public FlowType getFlowType() {
|
||||
return flowType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FunctionVertex getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FunctionVertex getEnd() {
|
||||
return end;
|
||||
}
|
||||
}
|
||||
|
||||
enum VertexType {
|
||||
|
||||
//@formatter:off
|
||||
BODY,
|
||||
ENTRY,
|
||||
EXIT,
|
||||
GROUP,
|
||||
SINGLETON;
|
||||
//@formatter:on
|
||||
|
||||
public boolean isEntry() {
|
||||
return this == ENTRY || this == SINGLETON;
|
||||
}
|
||||
|
||||
public boolean isExit() {
|
||||
return this == EXIT || this == SINGLETON;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,16 +1,26 @@
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import docking.widgets.filter.ContainsTextFilterFactory;
|
||||
import docking.widgets.filter.TextFilter;
|
||||
import ghidra.app.decompiler.DecompInterface;
|
||||
import ghidra.app.decompiler.DecompileOptions;
|
||||
import ghidra.app.decompiler.DecompileResults;
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.feature.fid.hash.FidHashQuad;
|
||||
import ghidra.feature.fid.service.FidService;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressFactory;
|
||||
import ghidra.program.model.address.AddressSet;
|
||||
import ghidra.program.model.address.AddressSetView;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.program.model.listing.CodeUnit;
|
||||
import ghidra.program.model.listing.Data;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.model.listing.FunctionManager;
|
||||
import ghidra.program.model.listing.Listing;
|
||||
import ghidra.program.model.mem.MemoryAccessException;
|
||||
import ghidra.program.model.pcode.HighFunction;
|
||||
import ghidra.program.model.pcode.PcodeOp;
|
||||
import ghidra.program.model.pcode.PcodeOpAST;
|
||||
@@ -19,56 +29,117 @@ import ghidra.program.model.symbol.Reference;
|
||||
import ghidra.program.model.symbol.ReferenceIterator;
|
||||
import ghidra.program.model.symbol.ReferenceManager;
|
||||
import ghidra.program.model.symbol.SourceType;
|
||||
import ghidra.program.util.string.FoundString;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
import ghidra.util.exception.InvalidInputException;
|
||||
|
||||
public class NamedScript extends GhidraScript {
|
||||
|
||||
long wxlog_full_hash = 0xf9f7e7c3081f5aa3L;
|
||||
long wxlog_spec_hash = 0x9e71b418c749e4faL;
|
||||
FidService service;
|
||||
|
||||
@Override
|
||||
protected void run() throws Exception {
|
||||
Address selectAddress = askAddress("选择log地址", "wechat log地址:");
|
||||
service = new FidService();
|
||||
|
||||
Address selectAddress = askAddress("填写手动确认的wxlog地址", "wxlog地址或者任意值进行搜索:");
|
||||
Listing listing = currentProgram.getListing();
|
||||
FunctionManager functionManager = currentProgram.getFunctionManager();
|
||||
ReferenceManager referenceManager = currentProgram.getReferenceManager();
|
||||
AddressFactory addressFactory = currentProgram.getAddressFactory();
|
||||
|
||||
AddressSpace space = addressFactory.getDefaultAddressSpace();
|
||||
AddressSpace[] addressSpaces = addressFactory.getAddressSpaces();
|
||||
|
||||
DecompInterface decompiler = new DecompInterface();
|
||||
DecompileOptions decompileOptions = new DecompileOptions();
|
||||
decompiler.setOptions(decompileOptions);
|
||||
decompiler.openProgram(currentProgram);
|
||||
|
||||
|
||||
Address funcAddress = selectAddress;
|
||||
|
||||
Function logFunction = functionManager.getFunctionAt(funcAddress);
|
||||
// for (AddressSpace sp : addressSpaces) {
|
||||
// funcAddress = sp.getAddress(selectAddress.getOffset());
|
||||
// logFunction = functionManager.getFunctionAt(funcAddress);
|
||||
// space = sp;
|
||||
// if (null != logFunction) {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
if (null == logFunction) {
|
||||
logFunction = findLogFunc();
|
||||
if (null == logFunction) {
|
||||
printerr("未能成功自动匹配wxlog函数,请手动查找后填写正确地址 ");
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ReferenceIterator referenceIterator = referenceManager.getReferencesTo(logFunction.getEntryPoint());
|
||||
for (Reference ref : referenceIterator) {
|
||||
Address fromAddress = ref.getFromAddress();
|
||||
// if (fromAddress.getOffset() != 0x18284bb19L) {
|
||||
// continue;
|
||||
// }
|
||||
handle(fromAddress, functionManager, decompiler, space, listing,selectAddress);
|
||||
println("caller address: " + fromAddress);
|
||||
while (referenceIterator.hasNext()) {
|
||||
monitor.checkCancelled();
|
||||
Reference next = referenceIterator.next();
|
||||
Address fromAddress = next.getFromAddress();
|
||||
println("lookup address: " + fromAddress.toString());
|
||||
handle(fromAddress, functionManager, decompiler, space, listing, selectAddress);
|
||||
println("caller address: " + fromAddress.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Function findLogFunc() throws MemoryAccessException, CancelledException {
|
||||
|
||||
FunctionManager functionManager = currentProgram.getFunctionManager();
|
||||
ReferenceManager referenceManager = currentProgram.getReferenceManager();
|
||||
AddressFactory factory = currentProgram.getAddressFactory();
|
||||
AddressSpace[] addressSpaces = factory.getAddressSpaces();
|
||||
AddressSetView initializedMemory = currentProgram.getMemory().getLoadedAndInitializedAddressSet();
|
||||
|
||||
AddressSet searchSet = initializedMemory.intersect(new AddressSet(initializedMemory));
|
||||
List<FoundString> findStrings = new ArrayList<>();
|
||||
println("初次查询速度较慢,请耐心等待。");
|
||||
for (AddressSpace space : addressSpaces) {
|
||||
if (monitor.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
AddressSet intersecting = searchSet.intersectRange(space.getMinAddress(), space.getMaxAddress());
|
||||
findStrings.addAll(findStrings(null, 10, 1, true, true));
|
||||
}
|
||||
|
||||
|
||||
if (null != findStrings && findStrings.size() > 0) {
|
||||
ContainsTextFilterFactory containsTextFilterFactory = new ContainsTextFilterFactory(false, true);
|
||||
TextFilter textFilter = containsTextFilterFactory.getTextFilter("(%d-%d-%d:%d:%02d:%02d:%03d %05d)-%s/%s:");
|
||||
for (FoundString foundString : findStrings) {
|
||||
if (monitor.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
String string = foundString.getString(currentProgram.getMemory());
|
||||
if (textFilter.matches(string)) {
|
||||
Address address = foundString.getAddress();
|
||||
|
||||
ReferenceIterator referencesTo = referenceManager.getReferencesTo(address);
|
||||
while (referencesTo.hasNext()) {
|
||||
if (monitor.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
Reference ref = referencesTo.next();
|
||||
Address wxlogAddr = ref.getFromAddress();
|
||||
Function targetFunction = functionManager.getFunctionContaining(wxlogAddr);
|
||||
if (null == targetFunction) {
|
||||
continue;
|
||||
}
|
||||
FidHashQuad hashQuad = service.hashFunction(targetFunction);
|
||||
if (hashQuad.getFullHash() == wxlog_full_hash
|
||||
&& hashQuad.getSpecificHash() == wxlog_spec_hash) {
|
||||
return targetFunction;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void handle(Address address, FunctionManager functionManager, DecompInterface decompiler,
|
||||
AddressSpace space, Listing listing,Address selectAddress) {
|
||||
AddressSpace space, Listing listing, Address selectAddress) {
|
||||
Function functionContaining = functionManager.getFunctionContaining(address);
|
||||
if (null == functionContaining) {
|
||||
println("no found function: " + address);
|
||||
println("no found function: " + address.toString());
|
||||
return;
|
||||
}
|
||||
DecompileResults res = decompiler.decompileFunction(functionContaining, 20, null);
|
||||
@@ -81,7 +152,6 @@ public class NamedScript extends GhidraScript {
|
||||
while (pcodeOps.hasNext()) {
|
||||
PcodeOpAST next = pcodeOps.next();
|
||||
int opcode = next.getOpcode();
|
||||
int numInputs = next.getNumInputs();
|
||||
if (PcodeOp.CALL == opcode || PcodeOp.CALLIND == opcode || PcodeOp.CALLOTHER == opcode) {
|
||||
Varnode input0 = next.getInput(0);
|
||||
boolean contains = input0.contains(selectAddress);
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
//
|
||||
// 根据一些日志类的相关函数的引用来获取当前函数的函数名
|
||||
// 输入被调用函数的地址和可以作为函数名称的参数的位置
|
||||
//
|
||||
//@category Functions
|
||||
import java.util.Iterator;
|
||||
|
||||
import ghidra.app.decompiler.DecompInterface;
|
||||
import ghidra.app.decompiler.DecompileOptions;
|
||||
import ghidra.app.decompiler.DecompileResults;
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.listing.CodeUnit;
|
||||
import ghidra.program.model.listing.Data;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.model.pcode.HighFunction;
|
||||
import ghidra.program.model.pcode.PcodeOp;
|
||||
import ghidra.program.model.pcode.PcodeOpAST;
|
||||
import ghidra.program.model.pcode.Varnode;
|
||||
import ghidra.program.model.symbol.Reference;
|
||||
import ghidra.program.model.symbol.ReferenceIterator;
|
||||
import ghidra.program.model.symbol.ReferenceManager;
|
||||
import ghidra.program.model.symbol.SourceType;
|
||||
import ghidra.util.StringUtilities;
|
||||
|
||||
public class RenameScript extends GhidraScript {
|
||||
|
||||
@Override
|
||||
protected void run() throws Exception {
|
||||
Address askAddress = askAddress("输入函数地址", "引用的函数地址");
|
||||
int askInt = askInt("输入参数位置", "函数名称的参数位置");
|
||||
DecompInterface decompiler = getDecompInterface();
|
||||
|
||||
ReferenceIterator referenceIterator = currentProgram.getReferenceManager().getReferencesTo(askAddress);
|
||||
for (Reference ref : referenceIterator) {
|
||||
monitor.checkCancelled();
|
||||
Address fromAddress = ref.getFromAddress();
|
||||
Function functionContaining = currentProgram.getFunctionManager().getFunctionContaining(fromAddress);
|
||||
if (null == functionContaining) {
|
||||
println("no found function: " + fromAddress.toString());
|
||||
continue;
|
||||
}
|
||||
DecompileResults res = decompiler.decompileFunction(functionContaining, 30, null);
|
||||
if (!res.decompileCompleted()) {
|
||||
println("decompile error: " + res.getErrorMessage());
|
||||
continue;
|
||||
}
|
||||
HighFunction highFunction = res.getHighFunction();
|
||||
Iterator<PcodeOpAST> pcodeOps = highFunction.getPcodeOps();
|
||||
|
||||
while (pcodeOps.hasNext()) {
|
||||
monitor.checkCancelled();
|
||||
PcodeOpAST opAST = pcodeOps.next();
|
||||
int opcode = opAST.getOpcode();
|
||||
if (PcodeOp.CALL == opcode || PcodeOp.CALLIND == opcode || PcodeOp.CALLOTHER == opcode) {
|
||||
Varnode input0 = opAST.getInput(0);
|
||||
boolean contains = input0.contains(askAddress);
|
||||
if (!contains) {
|
||||
continue;
|
||||
}
|
||||
Varnode inputVarnode = opAST.getInput(askInt);
|
||||
String nameString = null;
|
||||
if (inputVarnode.isUnique()) {
|
||||
nameString = getUniqueValue(inputVarnode);
|
||||
|
||||
} else if (inputVarnode.isConstant()) {
|
||||
nameString = getConstact(inputVarnode);
|
||||
}
|
||||
|
||||
if (StringUtilities.isAllBlank(nameString)) {
|
||||
continue;
|
||||
}
|
||||
String name = nameString.replace(" ", "");
|
||||
println("find function :" + name);
|
||||
SourceType signatureSource = functionContaining.getSignatureSource();
|
||||
if (signatureSource.isLowerPriorityThan(SourceType.USER_DEFINED)) {
|
||||
functionContaining.setName(name, SourceType.USER_DEFINED);
|
||||
currentProgram.getListing().setComment(functionContaining.getEntryPoint(), CodeUnit.POST_COMMENT,
|
||||
"script rename: " + name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private DecompInterface getDecompInterface() {
|
||||
DecompInterface decompiler = new DecompInterface();
|
||||
DecompileOptions decompileOptions = new DecompileOptions();
|
||||
decompiler.setOptions(decompileOptions);
|
||||
decompiler.openProgram(currentProgram);
|
||||
return decompiler;
|
||||
}
|
||||
|
||||
private String getConstact(Varnode input3) {
|
||||
Address address2 = input3.getAddress();
|
||||
Address address3 = toAddr(address2.getOffset());
|
||||
Data dataAt2 = getDataAt(address3);
|
||||
if (null != dataAt2) {
|
||||
if (dataAt2.hasStringValue()) {
|
||||
return dataAt2.getValue().toString();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getUniqueValue(Varnode input3) {
|
||||
PcodeOp def = input3.getDef();
|
||||
Varnode[] inputs = def.getInputs();
|
||||
if (null != inputs && inputs.length > 0) {
|
||||
if (inputs[0].isConstant()) {
|
||||
Address address2 = inputs[0].getAddress();
|
||||
Address address3 = toAddr(address2.getOffset());
|
||||
Data dataAt2 = currentProgram.getListing().getDataAt(address3);
|
||||
if (null != dataAt2) {
|
||||
if (dataAt2.hasStringValue()) {
|
||||
return dataAt2.getValue().toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user