Skip to content

Commit 11584f9

Browse files
committed
Fix breakpoint relocation
1 parent 184ea78 commit 11584f9

1 file changed

Lines changed: 67 additions & 23 deletions

File tree

x64dbgpython/x64dbgpython/BreakpointDlg.cpp

Lines changed: 67 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@ std::map<duint, std::string> g_BreakpointList;
1111

1212
void RefreshBpListBox(HWND hwnd);
1313
void CleanGarbageForBpMap();
14+
duint CalcBpHash(BRIDGEBP* bp);
15+
duint GetBpAtIndex(int index);
16+
duint GetBpHashAtIndex(int index);
1417

1518
//Plugin breakpoint callback handle
1619
void PluginHandleBreakpoint(CBTYPE cbType, PLUG_CB_BREAKPOINT* info)
1720
{
18-
duint breakAddr = info->breakpoint->addr;
19-
std::map<duint, std::string>::const_iterator iter = g_BreakpointList.find(breakAddr);
21+
std::map<duint, std::string>::const_iterator iter = g_BreakpointList.find(CalcBpHash(info->breakpoint));
2022
if (iter != g_BreakpointList.end())
2123
{
2224
try
@@ -33,15 +35,39 @@ void PluginHandleBreakpoint(CBTYPE cbType, PLUG_CB_BREAKPOINT* info)
3335
//Plugin handle save data
3436
void PluginHandleSaveDB(CBTYPE cbType, PLUG_CB_LOADSAVEDB* info)
3537
{
38+
CleanGarbageForBpMap();
3639
json_t* jsonBPList = nullptr;
3740
if (!g_BreakpointList.empty())
3841
{
3942
jsonBPList = json_array();
4043
for (auto it = g_BreakpointList.cbegin(); it != g_BreakpointList.end(); it++)
4144
{
4245
json_t* jsonBP = json_object();
43-
json_object_set_new(jsonBP, "addr", json_integer(it->first));
46+
47+
//Correct breakpoint module relocation
48+
49+
BPMAP bpList;
50+
DbgGetBpList(bp_none, &bpList);
51+
52+
BRIDGEBP* currBp = nullptr;
53+
for (int i = 0; i < bpList.count; i++)
54+
{
55+
if (CalcBpHash(&bpList.bp[i]) == it->first)
56+
{
57+
currBp = &bpList.bp[i];
58+
break;
59+
}
60+
}
61+
62+
if (currBp == nullptr)
63+
continue;
64+
65+
duint modBase = DbgFunctions()->ModBaseFromName(currBp->mod);
66+
duint newAddr = currBp->addr - modBase;
67+
68+
json_object_set_new(jsonBP, "addr", json_integer(newAddr));
4469
json_object_set_new(jsonBP, "command", json_string(it->second.c_str()));
70+
json_object_set_new(jsonBP, "mod", json_string(currBp->mod));
4571
json_array_append_new(jsonBPList, jsonBP);
4672
}
4773
json_object_set_new(info->root, "bpList", jsonBPList);
@@ -66,21 +92,19 @@ void PluginHandleLoadDB(CBTYPE cbType, PLUG_CB_LOADSAVEDB* info)
6692
{
6793
json_t* jsonAddr = json_object_get(jsonBP, "addr");
6894
json_t* jsonCommand = json_object_get(jsonBP, "command");
69-
if (json_is_integer(jsonAddr) && json_is_string(jsonCommand))
95+
json_t* jsonMod = json_object_get(jsonBP, "mod");
96+
if (json_is_integer(jsonAddr) && json_is_string(jsonCommand) && json_is_string(jsonMod))
7097
{
71-
g_BreakpointList.insert({ json_integer_value(jsonAddr), std::string(json_string_value(jsonCommand)) });
98+
const char* mod = json_string_value(jsonMod);
99+
duint offset = (duint)json_integer_value(jsonAddr);
100+
duint hash = _plugin_hash(mod, strlen(mod)) + offset;
101+
102+
g_BreakpointList.insert({ hash, std::string(json_string_value(jsonCommand)) });
72103
}
73104
}
74105
}
75106
}
76107

77-
duint GetBpAtIndex(int index)
78-
{
79-
BPMAP bpList;
80-
DbgGetBpList(bp_none, &bpList);
81-
return bpList.bp[index].addr;
82-
}
83-
84108
INT_PTR CALLBACK BreakpointDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
85109
{
86110
switch (uMsg)
@@ -118,8 +142,8 @@ INT_PTR CALLBACK BreakpointDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARA
118142
int pos = (int)SendMessage(bpListHwnd, LB_GETCURSEL, 0, 0);
119143
if (pos != -1)
120144
{
121-
duint bpAddr = GetBpAtIndex(pos);
122-
std::map<duint, std::string>::const_iterator iter = g_BreakpointList.find(bpAddr);
145+
duint bpHash = GetBpHashAtIndex(pos);
146+
std::map<duint, std::string>::const_iterator iter = g_BreakpointList.find(bpHash);
123147
if (iter != g_BreakpointList.end())
124148
{
125149
SetDlgItemTextA(hwndDlg, IDC_SCRIPTCONTENT, iter->second.c_str());
@@ -142,8 +166,8 @@ INT_PTR CALLBACK BreakpointDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARA
142166
DialogBoxParam(g_dllInstance, MAKEINTRESOURCE(IDD_SCRIPTEDITOR), hwndDlg, ScriptEditorProc, (LPARAM)pos);
143167
RefreshBpListBox(hwndDlg);
144168

145-
duint bpAddr = GetBpAtIndex(pos);
146-
std::map<duint, std::string>::const_iterator iter = g_BreakpointList.find(bpAddr);
169+
duint bpHash = GetBpHashAtIndex(pos);
170+
std::map<duint, std::string>::const_iterator iter = g_BreakpointList.find(bpHash);
147171
if (iter != g_BreakpointList.end())
148172
{
149173
SetDlgItemTextA(hwndDlg, IDC_SCRIPTCONTENT, iter->second.c_str());
@@ -172,8 +196,8 @@ INT_PTR CALLBACK ScriptEditorProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
172196
case WM_INITDIALOG:
173197
{
174198
g_CurrentBpSelection = (int)lParam;
175-
duint bpAddr = GetBpAtIndex(g_CurrentBpSelection);;
176-
std::map<duint, std::string>::const_iterator iter = g_BreakpointList.find(bpAddr);
199+
duint bpHash = GetBpHashAtIndex(g_CurrentBpSelection);;
200+
std::map<duint, std::string>::const_iterator iter = g_BreakpointList.find(bpHash);
177201
if (iter != g_BreakpointList.end())
178202
{
179203
SetDlgItemTextA(hwndDlg, IDC_SCRIPT, iter->second.c_str());
@@ -191,21 +215,21 @@ INT_PTR CALLBACK ScriptEditorProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
191215
{
192216
if (HIWORD(wParam) == BN_CLICKED)
193217
{
194-
duint bpAddr = GetBpAtIndex(g_CurrentBpSelection);
218+
duint bpHash = GetBpHashAtIndex(g_CurrentBpSelection);
195219

196220
HWND scriptTextHwnd = GetDlgItem(hwndDlg, IDC_SCRIPT);
197221
unsigned int scriptLength = GetWindowTextLengthA(scriptTextHwnd);
198222
char* scriptContent = new char[(unsigned long long)scriptLength + 2];
199223
GetDlgItemTextA(hwndDlg, IDC_SCRIPT, scriptContent, scriptLength + 1);
200224

201-
std::map<duint, std::string>::const_iterator iter = g_BreakpointList.find(bpAddr);
225+
std::map<duint, std::string>::const_iterator iter = g_BreakpointList.find(bpHash);
202226
if (iter != g_BreakpointList.end())
203227
{
204228
g_BreakpointList.erase(iter);
205229
}
206230

207231
if (scriptLength)
208-
g_BreakpointList.insert({ bpAddr, std::string(scriptContent) });
232+
g_BreakpointList.insert({ bpHash, std::string(scriptContent) });
209233

210234
delete[] scriptContent;
211235

@@ -231,7 +255,7 @@ void RefreshBpListBox(HWND hwnd)
231255
{
232256
wchar_t bpAddrText[20];
233257

234-
if (g_BreakpointList.find(bpList.bp[i].addr) != g_BreakpointList.end())
258+
if (g_BreakpointList.find(CalcBpHash(&bpList.bp[i])) != g_BreakpointList.end())
235259
swprintf(bpAddrText, sizeof(bpAddrText) / 2, L"%p*", (void*)bpList.bp[i].addr);
236260
else
237261
swprintf(bpAddrText, sizeof(bpAddrText) / 2, L"%p", (void*)bpList.bp[i].addr);
@@ -249,7 +273,7 @@ void CleanGarbageForBpMap()
249273
bool isHaveInBpList = false;
250274
for (int i = 0; i < bpList.count; i++)
251275
{
252-
if (bpList.bp[i].addr == it->first)
276+
if (CalcBpHash(&bpList.bp[i]) == it->first)
253277
{
254278
isHaveInBpList = true;
255279
break;
@@ -260,4 +284,24 @@ void CleanGarbageForBpMap()
260284
else
261285
it++;
262286
}
287+
}
288+
289+
duint CalcBpHash(BRIDGEBP* bp)
290+
{
291+
duint offset = bp->addr - DbgFunctions()->ModBaseFromName(bp->mod);
292+
return _plugin_hash(bp->mod, strlen(bp->mod)) + offset;
293+
}
294+
295+
duint GetBpAtIndex(int index)
296+
{
297+
BPMAP bpList;
298+
DbgGetBpList(bp_none, &bpList);
299+
return bpList.bp[index].addr;
300+
}
301+
302+
duint GetBpHashAtIndex(int index)
303+
{
304+
BPMAP bpList;
305+
DbgGetBpList(bp_none, &bpList);
306+
return CalcBpHash(&bpList.bp[index]);
263307
}

0 commit comments

Comments
 (0)