1
0
Fork 0

Compare commits

...

86 Commits

Author SHA1 Message Date
Duncan Ogilvie a4be9f87f5
Merge pull request #3234 from x64dbg/handle-anti-debug
Fix an anti-debug trick used by GuLoader
2023-10-05 13:33:02 +02:00
Duncan Ogilvie 56ee888a0b
Merge pull request #3233 from x64dbg/fix-3198
Fix #3198: Implement GuiSelectionSet for GUI_MEMMAP
2023-10-05 13:27:27 +02:00
Duncan Ogilvie 3e1b3d61bc
Merge pull request #3231 from torusrxxx/torusrxxx-patch-1
Fix QObject::connect: No such slot SourceView::followDisassemblerSlot()
2023-10-05 13:26:56 +02:00
Duncan Ogilvie ffb6de5b56 Fix an anti-debug trick used by GuLoader
Closes #2749
Closes #2504
2023-10-05 13:12:46 +02:00
ζeh Matt f6c3e4219a
Fix #3198: Implement GuiSelectionSet for GUI_MEMMAP 2023-10-03 21:37:08 +03:00
Torusrxxx c589bb57c8
Fix QObject::connect: No such signal SourceView::showCpu() 2023-10-03 14:27:22 +00:00
Torusrxxx 6e1a5000e8
Fix QObject::connect: No such slot SourceView::followDisassemblerSlot() 2023-10-03 14:26:00 +00:00
Duncan Ogilvie bba369d607
Merge pull request #3219 from ZehMatt/plugin-dirs
Add support for plugins in sub directories
2023-10-01 22:38:42 +02:00
Duncan Ogilvie 437573276b Fix a potential bug where a plugin handle is reused 2023-10-01 22:28:50 +02:00
Duncan Ogilvie e3adaaac5d Simplify pluginload and rename globals 2023-10-01 20:46:52 +02:00
Duncan Ogilvie 5628094e17
Merge pull request #3217 from HayFieldLaps/commandparser-network-path
commandparser handle UNC paths
2023-10-01 13:01:14 +02:00
dad 4ad555a509 commandparser handle UNC paths 2023-10-01 13:00:11 +02:00
Duncan Ogilvie 8820440f06
Merge pull request #3223 from shocoman/symbols-view-slowdown 2023-10-01 12:51:58 +02:00
Duncan Ogilvie 51e697b726
Merge pull request #3225 from HayFieldLaps/tabwidget-delete-on-close
free MHDetachedWindow on reattach
2023-10-01 12:49:21 +02:00
Duncan Ogilvie 56c3249e75
Merge pull request #3226 from HayFieldLaps/hexeditdialog-patch
Hide Keep Size QCheckBox from all but Binary Edit
2023-10-01 12:48:53 +02:00
dad 13bd1f3164 Hide Keep Size QCheckBox from all but Binary Edit 2023-09-22 12:50:38 -06:00
dad 335d94d2d9 free MHDetachedWindow on reattach 2023-09-22 11:58:01 -06:00
shocoman b74f6b5d5d SymbolView: Don't update fonts on each 'repaintTableView' event 2023-09-22 13:24:24 +07:00
ζeh Matt 68112f51da
Add plugin directory to the search path 2023-09-21 12:58:01 +03:00
ζeh Matt e2b658f0a3
Fix file check 2023-09-21 12:46:31 +03:00
ζeh Matt ce73e9cdf7
Warn the user about duplicate plugins 2023-09-21 11:49:47 +03:00
ζeh Matt ef925bcfa7
Disallow loading plugins with the same name when they exist in sub dirs 2023-09-21 11:39:52 +03:00
ζeh Matt df8bdfe1fb
Fix printing the plugin name 2023-09-21 11:13:00 +03:00
ζeh Matt 7fcb626ba2
Fix loading plugins more than once, remove obsolete isLoaded member 2023-09-21 10:59:11 +03:00
ζeh Matt 517c82604f
Refactor plugin load/unload to only require the name 2023-09-21 10:56:59 +03:00
ζeh Matt c28653700a
Refactor the conditional plugin extension definitions 2023-09-21 09:51:26 +03:00
ζeh Matt 0f5bc725f8
Initial support to load plugins from a sub directory 2023-09-21 09:43:51 +03:00
Duncan Ogilvie c65c956f85 Move the header separator one pixel down 2023-09-21 00:47:54 +02:00
Duncan Ogilvie 3beec936ec Fix the missing configuration for the table header background
Closes #3218
2023-09-21 00:29:43 +02:00
Duncan Ogilvie 7f2566b6ed
Merge pull request #3192 from x64dbg/cross-platform-preparations
Cross platform preparations
2023-09-20 02:30:40 +02:00
Duncan Ogilvie 7c00347a24
Merge pull request #3211 from GermanAizek/fix
Fixed catch exception std::bad_alloc and close handle hFile if downslib::inetopen
2023-09-20 02:28:59 +02:00
Duncan Ogilvie fdc97fe6d1 Properly restore DisassemblyPopup functionality 2023-09-19 08:06:03 +02:00
Duncan Ogilvie a349f9c05f Fix a bug in the extension handling for trace files 2023-09-19 06:50:44 +02:00
Герман Семенов bdb38d6a97 Fixed catch std::bad_alloc and close handle hFile if downslib::inetopen 2023-09-19 06:41:24 +02:00
Duncan Ogilvie e2d1d79930 Fix a bug where a column width of 0 would not adjust correctly 2023-09-19 06:40:38 +02:00
Duncan Ogilvie 7733012330 Refactor AbstractTableView for cross-platform 2023-09-19 06:25:33 +02:00
Duncan Ogilvie 663bfbbb06 Refactor parent = 0 -> parent = nullptr 2023-09-19 06:25:33 +02:00
Duncan Ogilvie 5797dae1c3 Update Zydis in the UI and remove DisassemblyPopup 2023-09-19 06:25:33 +02:00
Duncan Ogilvie 812c91d361 Get rid of the wLocal variable naming convention (mostly) 2023-09-19 06:25:33 +02:00
Duncan Ogilvie 6fba4478fb Remove the unused translations submodule 2023-09-19 06:25:33 +02:00
Duncan Ogilvie 952c16aad7 Update zydis_wrapper 2023-09-19 06:25:33 +02:00
Duncan Ogilvie b22266b822 Bump Zydis to 4.0.0 2023-09-19 06:25:32 +02:00
Duncan Ogilvie 3d56c4fd35 Remove the Zydis submodule 2023-09-19 06:25:32 +02:00
Duncan Ogilvie 7e9a89847e
Merge pull request #3213 from torusrxxx/patch000000f9
delete widget when closing tab
2023-09-16 13:31:34 +02:00
Duncan Ogilvie 6228bfe2bf
Merge pull request #3212 from GermanAizek/emplace
Replaced pushes and inserts to emplace for compact code
2023-09-16 13:21:24 +02:00
torusrxxx 9fa8c8cea0
delete widget when closing tab 2023-09-16 09:30:24 +08:00
German Semenov 11d96f1878 Replaced inserts to emplace for compact code and improved code generation by compiler 2023-09-12 19:13:40 +03:00
Duncan Ogilvie dd91e4376a
Merge pull request #3203 from torusrxxx/patch000000f8
Add UI for mnemonichelp
2023-09-12 10:58:23 +02:00
Duncan Ogilvie 2ce5a283f5
Merge pull request #3206 from HayFieldLaps/referenceview-cycle-filtered
Fixed cycling through filtered references without clearing filter.
2023-09-12 10:57:38 +02:00
Duncan Ogilvie 02c762ff4a
Merge pull request #3208 from shocoman/disasm-popup-border
Dark theme: fix several visibility issues
2023-09-12 10:57:00 +02:00
Duncan Ogilvie cdee7fed64
Merge pull request #3209 from HayFieldLaps/bookmark-clear
Fix typo in bookmarkclear command
2023-09-12 10:56:25 +02:00
dad b6be841a48 Fix typo in bookmarkclear command 2023-09-07 12:24:50 -06:00
shocoman bc3d7574bc Dark theme: fix several visibility issues 2023-09-08 00:03:33 +07:00
dad 7405acd42d Fixed cycling through filtered references without clearing filter.
Allow "Actions -> Go to Next/Previous Reference" to cycle through a filtered reference list.  Was previously clearing the filter on the first "Next/Previous" action.
2023-09-04 13:25:32 -06:00
torusrxxx 3616f2d33a
Add UI for mnemonichelp 2023-09-02 21:34:45 +08:00
Duncan Ogilvie b28e317073
Merge pull request #3197 from shocoman/fill-view-background-border
Dark theme: Make QHexEdit background color brighter for visibility
2023-09-02 14:26:47 +02:00
Duncan Ogilvie 323d318329
Merge pull request #3199 from HayFieldLaps/searchlistview-escape-fix
Pass Escape key event if search text is empty
2023-09-02 14:26:11 +02:00
Duncan Ogilvie d08773d3c7
Merge pull request #3201 from f09f9095/extra-period-when-saving-trace-dump
removed extra dot when saving trace dump
2023-09-02 14:25:39 +02:00
f09f9095 5659f7db2c removed extra dot when saving trace dump 2023-08-30 07:44:43 -04:00
dad d68e1d44a8 Pass Escape key event if search text is empty
Was blocking Esc from closing Attach window.
2023-08-29 14:37:16 -06:00
shocoman b3dc97c4a5 Dark theme: Make QHexEdit background color brighter for visibility 2023-08-29 12:25:15 +07:00
Duncan Ogilvie 48d81226ed
Merge pull request #3189 from Kasuromi/development
Fix grammar in readme
2023-08-26 13:36:05 +02:00
Kasuromi f557751365
Fix typos in readme 2023-08-26 14:31:23 +03:00
Duncan Ogilvie 4a767ea507
Merge pull request #3188 from ZehMatt/query-page
Start enumerating memory pages at minimum application address
2023-08-25 12:21:32 +02:00
ζeh Matt 8c6f3089e9
Start enumerating memory pages at minimum application address 2023-08-25 13:15:07 +03:00
Duncan Ogilvie 4e5c2bd9c4 Fix regression where comments are not showing at all
Thanks MHR for the report!
2023-08-24 19:03:02 +02:00
Duncan Ogilvie 7d00017e69
Merge pull request #3185 from GermanAizek/development
Using reserve and unordered_map for optimize inserts
2023-08-24 10:33:23 +02:00
German Semenov 145053d8ae Using reserve for optimize inserts in loops
Signed-off-by: German Semenov <GermanAizek@yandex.ru>
2023-08-24 11:05:37 +03:00
Duncan Ogilvie e6b43cdc6c
Merge pull request #3180 from shocoman/cpu-flags-help-tooltip
Show a tooltip with a sorted list of flags in the Register View
2023-08-23 12:56:16 +02:00
shocoman 4301af38a9 Show a tooltip with a sorted list of flags in the Register View 2023-08-23 17:30:44 +07:00
Duncan Ogilvie 78f37958eb
Merge pull request #3183 from HayFieldLaps/searchlistview-copy
CTRL + C functionality in AbstractStdTable/SearchListView
2023-08-23 01:09:16 +02:00
Duncan Ogilvie 9f046b96e2 Rename 'Switch view' to 'Region view' and 'Section view'
Also reduces the log trigger
2023-08-23 01:00:33 +02:00
dad 414c9cb23e CTRL + C functionality in AbstractStdTable/SearchListView
-CTRL + C functions properly in SearchListView
-CTRL + A when search box is empty selects all rows in table (if allowed)
-SHIFT + HOME/END when search box is empty selects rows from table (if allowed)
-ESC clears the filter rather than just the Search edit line
2023-08-22 13:09:07 -06:00
Duncan Ogilvie a85f177567
Merge pull request #3176 from torusrxxx/patch000000f6
Added mnemonic brief column and keeps mnemonic brief configuration
2023-08-20 12:55:07 +02:00
Torusrxxx b477ffc490
Add isdebuggeefocused, and optimized isdebuggerfocused (#3175)
* Add isdebuggeefocused, and optimized isdebuggerfocused

* Add rdtsc() expression function

* Added isprocessfocused()
2023-08-20 12:54:40 +02:00
shocoman 7bf53e72f1
In Graph mode, also apply highlighting to different sizes of the same register (#3174) 2023-08-20 12:54:18 +02:00
HayFieldLaps 6b05405714
Set dump index from ACTIVEVIEW (#3172) 2023-08-20 12:53:20 +02:00
torusrxxx f475f7d841
Allow customizing trace disassembler context menu 2023-08-15 23:09:42 +08:00
torusrxxx 479fdaf38d
Added mnemonic brief column and keeps mnemonic brief configuration 2023-08-15 22:25:42 +08:00
Duncan Ogilvie b8c2aad3b3 Also restore window size for dialogs
saveWindowPos -> saveWindowGeometry

#3171
2023-08-15 09:34:07 +02:00
Duncan Ogilvie 59b5d923cd Reduce 'Disassembly' column size when searching references
Closes #3171
2023-08-15 09:12:45 +02:00
Duncan Ogilvie 3151aa6280 Don't fail when reading memory in expression string functions 2023-08-12 17:00:05 +02:00
Duncan Ogilvie 6a970e657d
Merge pull request #3165 from HayFieldLaps/memory-map-view-sort
Add secondary sorting to Memory Map
2023-08-10 17:33:12 +02:00
dad 791d6ba59c Remove pointer comparisons in StdTable
This solves the unstable sorting within the Memory Map view, I did a fairly thorough test to see if it affects any of the other sortable table views and didn't notice any issues.
2023-08-09 16:20:43 -06:00
dad d5901879a7 Revert "Add secondary sorting to Memory Map"
This reverts commit 6cd26dd3dd.
2023-08-09 16:13:31 -06:00
dad 6cd26dd3dd Add secondary sorting to Memory Map
Fixed unstable sorting in Memory Map when sorting by Type, Protection or
Initial (Protection). To resolve this, a secondary sort is now performed
on Address (only in ascending order) for rows with equal values. This
change affects MemoryMapView::sortRows and results in QString::compare
being called twice (also in StdTable::SortBy::AsText), introducing
additional computational complexity. Further optimization may be needed.
2023-08-08 14:20:04 -06:00
231 changed files with 72113 additions and 4816 deletions

8
.gitmodules vendored
View File

@ -1,13 +1,7 @@
[submodule "src/gui/Translations"]
path = src/gui/Translations
url = ../Translations.git
[submodule "src/dbg/btparser"]
path = src/dbg/btparser
url = ../btparser
[submodule "deps"]
path = deps
url = ../deps
shallow = true
[submodule "src/zydis_wrapper/zydis"]
path = src/zydis_wrapper/zydis
url = ../zydis.git
shallow = true

View File

@ -21,7 +21,7 @@ An open-source binary debugger for Windows, aimed at malware analysis and revers
1. Download a snapshot from [GitHub](https://github.com/x64dbg/x64dbg/releases), [SourceForge](https://sourceforge.net/projects/x64dbg/files/snapshots) or [OSDN](https://osdn.net/projects/x64dbg) and extract it in a location your user has write access to.
2. _Optionally_ use `x96dbg.exe` to register a shell extension and add shortcuts to your desktop.
3. You can now run `x32\x32dbg.exe` if you want to debug a 32-bit executable or `x64\x64dbg.exe` to debug a 64-bit executable! If you are unsure you can always run `x96dbg.exe` and chose your architecture there.
3. You can now run `x32\x32dbg.exe` if you want to debug a 32-bit executable or `x64\x64dbg.exe` to debug a 64-bit executable! If you are unsure you can always run `x96dbg.exe` and choose your architecture there.
You can also [compile](https://github.com/x64dbg/x64dbg/wiki/Compiling-the-whole-project) x64dbg yourself with a few easy steps!
@ -92,4 +92,4 @@ You can find an exhaustive list of GitHub contributors [here](https://github.com
- [mrfearless](https://twitter.com/fearless0)
- [JustMagic](https://github.com/JustasMasiulis)
Without the help of many people and other open-source projects, it would not have been possible to make x64dbg what is it today, thank you!
Without the help of many people and other open-source projects, it would not have been possible to make x64dbg what it is today, thank you!

View File

@ -196,9 +196,9 @@ QMenuBar::item:disabled:selected {
}
QMenu {
border: 1px solid #212121;
border: 1px solid #808080;
color: #e0e0e0;
margin: 2px;
padding: 2px;
}
QMenu::icon {
@ -281,7 +281,7 @@ QMenu::right-arrow {
}
QWidget:disabled {
color: #454545;
color: #646464;
background-color: #212121;
}
@ -313,6 +313,11 @@ QLineEdit {
color: #e0e0e0;
}
/* e.g. "System breakpoint scripts" dialog */
QLineEdit:disabled {
background-color: #282828;
}
QAbstractItemView QLineEdit {
padding: 0;
}
@ -501,7 +506,7 @@ QMainWindow::separator:hover {
QMenu::separator {
height: 1px;
background-color: #2a2b2f;
background-color: #808080;
color: white;
padding-left: 4px;
margin-left: 10px;
@ -550,7 +555,7 @@ QPushButton {
color: #e0e0e0;
background-color: #212121;
border-width: 1px;
border-color: #2a2b2f;
border-color: #808080;
border-style: solid;
padding: 5px;
border-radius: 2px;
@ -567,7 +572,7 @@ QPushButton:disabled {
padding-left: 10px;
padding-right: 10px;
border-radius: 2px;
color: #454545;
color: #646464;
}
QPushButton:focus {
@ -581,11 +586,11 @@ QPushButton:pressed {
padding-bottom: -17px;
}
QComboBox {
QComboBox, QFontComboBox {
selection-background-color: #89a2f6;
selection-color: #000000;
border-style: solid;
border: 1px solid #212121;
border: 1px solid #424242;
border-radius: 2px;
padding: 5px;
min-width: 75px;
@ -596,15 +601,19 @@ QPushButton:checked {
border-color: #2a2b2f;
}
QPushButton:hover {
border: 1px solid #e0e0e0;
color: #e0e0e0;
}
QComboBox:hover,
QPushButton:hover,
QAbstractSpinBox:hover,
QLineEdit:hover,
QTextEdit:hover,
QPlainTextEdit:hover,
QAbstractView:hover,
QTreeView:hover {
border: 1px solid #414141;
border: 1px solid #646464;
color: #e0e0e0;
}
@ -619,6 +628,7 @@ QComboBox QAbstractItemView {
border-radius: 2px;
border: 1px solid #212121;
selection-background-color: #414141;
selection-color: #ffffff; /* e.g. calling convention ComboBox */
}
QComboBox::drop-down {
@ -1096,4 +1106,13 @@ QTabWidget::pane {
QTabBar::tear {
width: 0px;
border: none;
}
}
/* e.g. "Exception filters" list, "Patch file" modules list, "Set page memory rights" table, "Select font" list, etc */
QTableView, QListView {
selection-color: #c8c8c8;
}
DisassemblyPopup {
border: 1px solid #c0c0c0;
}

View File

@ -1,6 +1,7 @@
[Colors]
AbstractTableViewBackgroundColor=#212121
AbstractTableViewHeaderTextColor=#E0E0E0
AbstractTableViewHeaderBackgroundColor=#414141
AbstractTableViewSelectionColor=#414141
AbstractTableViewSeparatorColor=#717171
AbstractTableViewTextColor=#E0E0E0
@ -51,7 +52,7 @@ DisassemblyCommentColor=#E0E0E0
DisassemblyConditionalJumpLineFalseColor=#808080
DisassemblyConditionalJumpLineTrueColor=#AA0000
DisassemblyFunctionColor=#F88478
DisassemblyHardwareBreakpointBackgroundColor=#XXXXXX
DisassemblyHardwareBreakpointBackgroundColor=#000000
DisassemblyHardwareBreakpointColor=#E6E976
DisassemblyLabelBackgroundColor=#XXXXXX
DisassemblyLabelColor=#B794F6
@ -105,10 +106,10 @@ HexDumpUnknownCodePointerHighlightColor=#0000FF
HexDumpUnknownDataPointerHighlightColor=#89A2F6
HexDumpUserModuleCodePointerHighlightColor=#00FF00
HexDumpUserModuleDataPointerHighlightColor=#008000
HexEditBackgroundColor=#212121
HexEditSelectionColor=#414141
HexEditBackgroundColor=#313131
HexEditSelectionColor=#515151
HexEditTextColor=#E0E0E0
HexEditWildcardColor=#C60000
HexEditWildcardColor=#FF0000
InstructionAddressBackgroundColor=#XXXXXX
InstructionAddressColor=#F88478
InstructionCallBackgroundColor=#XXXXXX

View File

@ -2015,11 +2015,6 @@ BRIDGE_IMPEXP DWORD GuiGetMainThreadId()
return (DWORD)(duint)_gui_sendmessage(GUI_GET_MAIN_THREAD_ID, nullptr, nullptr);
}
BRIDGE_IMPEXP bool GuiIsDebuggerFocused()
{
return !!(duint)_gui_sendmessage(GUI_IS_DEBUGGER_FOCUSED, nullptr, nullptr);
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
hInst = hinstDLL;

View File

@ -176,7 +176,10 @@ extern "C"
#define MAX_SECTION_SIZE 10
#define MAX_COMMAND_LINE_SIZE 256
#define MAX_MNEMONIC_SIZE 64
#ifndef PAGE_SIZE
#define PAGE_SIZE 0x1000
#endif // PAGE_SIZE
//Debugger enums
typedef enum
@ -1126,7 +1129,6 @@ BRIDGE_IMPEXP void DbgGetSymbolInfo(const SYMBOLPTR* symbolptr, SYMBOLINFO* info
BRIDGE_IMPEXP DEBUG_ENGINE DbgGetDebugEngine();
BRIDGE_IMPEXP bool DbgGetSymbolInfoAt(duint addr, SYMBOLINFO* info);
BRIDGE_IMPEXP duint DbgXrefAddMulti(const XREF_EDGE* edges, duint count);
BRIDGE_IMPEXP bool GuiIsDebuggerFocused();
//Gui defines
typedef enum
@ -1275,7 +1277,7 @@ typedef enum
GUI_GET_MAIN_THREAD_ID, // param1=unused, param2=unused
GUI_ADD_MSG_TO_LOG_HTML, // param1=(const char*)msg, param2=unused
GUI_IS_LOG_ENABLED, // param1=unused, param2=unused
GUI_IS_DEBUGGER_FOCUSED, // param1=unused, param2=unused
GUI_IS_DEBUGGER_FOCUSED_UNUSED, // This message is removed, could be used for future purposes
GUI_SAVE_LOG, // param1=const char* file name,param2=unused
GUI_REDIRECT_LOG, // param1=const char* file name,param2=unused
GUI_STOP_REDIRECT_LOG, // param1=unused, param2=unused

View File

@ -73,7 +73,7 @@ bool TraceRecordManager::setTraceRecordType(duint pageAddress, TraceRecordType t
newPage.moduleIndex = ~0;
}
auto inserted = TraceRecord.insert(std::make_pair(ModHashFromAddr(pageAddress), newPage));
auto inserted = TraceRecord.emplace(ModHashFromAddr(pageAddress), newPage);
if(inserted.second == false) // we failed to insert new page into the map
{
efree(newPage.rawPtr);
@ -205,14 +205,14 @@ void TraceRecordManager::TraceExecute(duint address, duint size)
//See https://www.felixcloutier.com/x86/FXSAVE.html, max 512 bytes
#define memoryContentSize 512
static void HandleZydisOperand(const Zydis & cp, int opindex, DISASM_ARGTYPE* argType, duint* value, unsigned char memoryContent[memoryContentSize], unsigned char* memorySize)
static void HandleZydisOperand(const Zydis & zydis, int opindex, DISASM_ARGTYPE* argType, duint* value, unsigned char memoryContent[memoryContentSize], unsigned char* memorySize)
{
*value = cp.ResolveOpValue(opindex, [&cp](ZydisRegister reg)
*value = (duint)zydis.ResolveOpValue(opindex, [&zydis](ZydisRegister reg) -> uint64_t
{
auto regName = cp.RegName(reg);
auto regName = zydis.RegName(reg);
return regName ? getregister(nullptr, regName) : 0; //TODO: temporary needs enums + caching
});
const auto & op = cp[opindex];
const auto & op = zydis[opindex];
switch(op.type)
{
case ZYDIS_OPERAND_TYPE_REGISTER:
@ -269,7 +269,7 @@ void TraceRecordManager::TraceExecuteRecord(const Zydis & newInstruction)
if(newInstruction.Success() && !newInstruction.IsNop() && newInstruction.GetId() != ZYDIS_MNEMONIC_LEA)
{
// This can happen when trace execute instruction is used, we need to fix that or something would go wrong with the GUI.
newContext.registers.regcontext.cip = newInstruction.Address();
newContext.registers.regcontext.cip = (duint)newInstruction.Address();
DISASM_ARGTYPE argType;
duint value;
unsigned char memoryContent[memoryContentSize];
@ -553,13 +553,13 @@ bool TraceRecordManager::enableTraceRecording(bool enabled, const char* fileName
for(size_t i = 0; i < _countof(rtOldContextChanged); i++)
rtOldContextChanged[i] = true;
dprintf(QT_TRANSLATE_NOOP("DBG", "Started trace recording to file: %s\r\n"), fileName);
Zydis cp;
Zydis zydis;
unsigned char instr[MAX_DISASM_BUFFER];
auto cip = GetContextDataEx(hActiveThread, UE_CIP);
if(MemRead(cip, instr, MAX_DISASM_BUFFER))
{
cp.DisassembleSafe(cip, instr, MAX_DISASM_BUFFER);
TraceExecuteRecord(cp);
zydis.DisassembleSafe(cip, instr, MAX_DISASM_BUFFER);
TraceExecuteRecord(zydis);
}
GuiOpenTraceFile(fileName);
return true;
@ -683,7 +683,7 @@ void TraceRecordManager::loadFromDb(JSON root)
currentPage.moduleIndex = ~0;
key = currentPage.rva;
}
TraceRecord.insert(std::make_pair(key, currentPage));
TraceRecord.emplace(key, currentPage);
}
else
efree(currentPage.rawPtr, "TraceRecordManager");

View File

@ -67,7 +67,10 @@ downslib_error downslib_download(const char* url,
0);
if(!hInternet)
{
CloseHandle(hFile);
return downslib_error::inetopen;
}
// Set a time-out value in milliseconds
InternetSetOptionA(hInternet,

View File

@ -102,8 +102,8 @@ extern "C" DLL_EXPORT bool _dbg_isjumpgoingtoexecute(duint addr)
unsigned char data[16];
if(MemRead(addr, data, sizeof(data), nullptr, true))
{
Zydis cp;
if(cp.Disassemble(addr, data))
Zydis zydis;
if(zydis.Disassemble(addr, data))
{
CONTEXT ctx;
memset(&ctx, 0, sizeof(ctx));
@ -116,7 +116,7 @@ extern "C" DLL_EXPORT bool _dbg_isjumpgoingtoexecute(duint addr)
auto cflags = ctx.EFlags;
auto ccx = ctx.Ecx;
#endif //_WIN64
return cp.IsBranchGoingToExecute(cflags, ccx);
return zydis.IsBranchGoingToExecute(cflags, ccx);
}
}
return false;
@ -329,11 +329,11 @@ static bool getAutoComment(duint addr, String & comment)
BRIDGE_ADDRINFO newinfo;
char string_text[MAX_STRING_SIZE] = "";
Zydis cp;
Zydis zydis;
auto getregs = !bOnlyCipAutoComments || addr == lastContext.cip;
disasmget(cp, addr, &instr, getregs);
disasmget(zydis, addr, &instr, getregs);
// Some nop variants have 'operands' that should be ignored
if(cp.Success() && !cp.IsNop())
if(zydis.Success() && !zydis.IsNop())
{
//Ignore register values when not on CIP and OnlyCipAutoComments is enabled: https://github.com/x64dbg/x64dbg/issues/1383
if(!getregs)
@ -342,7 +342,7 @@ static bool getAutoComment(duint addr, String & comment)
instr.arg[i].value = instr.arg[i].constant;
}
if(addr == lastContext.cip && (cp.GetId() == ZYDIS_MNEMONIC_SYSCALL || (cp.GetId() == ZYDIS_MNEMONIC_INT && cp[0].imm.value.u == 0x2e)))
if(addr == lastContext.cip && (zydis.GetId() == ZYDIS_MNEMONIC_SYSCALL || (zydis.GetId() == ZYDIS_MNEMONIC_INT && zydis[0].imm.value.u == 0x2e)))
{
auto syscallName = SyscallToName((unsigned int)lastContext.cax);
if(!syscallName.empty())
@ -367,9 +367,9 @@ static bool getAutoComment(duint addr, String & comment)
if(instr.arg[i].constant == instr.arg[i].value) //avoid: call <module.label> ; addr:label
{
auto constant = instr.arg[i].constant;
if(instr.arg[i].type == arg_normal && instr.arg[i].value == addr + instr.instr_size && cp.IsCall())
if(instr.arg[i].type == arg_normal && instr.arg[i].value == addr + instr.instr_size && zydis.IsCall())
temp_string.assign("call $0");
else if(instr.arg[i].type == arg_normal && instr.arg[i].value == addr + instr.instr_size && cp.IsJump())
else if(instr.arg[i].type == arg_normal && instr.arg[i].value == addr + instr.instr_size && zydis.IsJump())
temp_string.assign("jmp $0");
else if(instr.type == instr_branch)
continue;
@ -881,12 +881,12 @@ extern "C" DLL_EXPORT duint _dbg_getbranchdestination(duint addr)
unsigned char data[MAX_DISASM_BUFFER];
if(!MemIsValidReadPtr(addr, true) || !MemRead(addr, data, sizeof(data)))
return 0;
Zydis cp;
if(!cp.Disassemble(addr, data))
Zydis zydis;
if(!zydis.Disassemble(addr, data))
return 0;
if(cp.IsBranchType(Zydis::BTJmp | Zydis::BTCall | Zydis::BTLoop | Zydis::BTXbegin))
if(zydis.IsBranchType(Zydis::BTJmp | Zydis::BTCall | Zydis::BTLoop | Zydis::BTXbegin))
{
auto opValue = cp.ResolveOpValue(0, [](ZydisRegister reg) -> size_t
auto opValue = (duint)zydis.ResolveOpValue(0, [](ZydisRegister reg) -> uint64_t
{
switch(reg)
{
@ -949,10 +949,10 @@ extern "C" DLL_EXPORT duint _dbg_getbranchdestination(duint addr)
return 0;
}
});
if(cp.OpCount() && cp[0].type == ZYDIS_OPERAND_TYPE_MEMORY)
if(zydis.OpCount() && zydis[0].type == ZYDIS_OPERAND_TYPE_MEMORY)
{
auto const tebseg = ArchValue(ZYDIS_REGISTER_FS, ZYDIS_REGISTER_GS);
if(cp[0].mem.segment == tebseg)
if(zydis[0].mem.segment == tebseg)
opValue += duint(GetTEBLocation(hActiveThread));
if(MemRead(opValue, &opValue, sizeof(opValue)))
return opValue;
@ -960,7 +960,7 @@ extern "C" DLL_EXPORT duint _dbg_getbranchdestination(duint addr)
else
return opValue;
}
if(cp.IsRet())
if(zydis.IsRet())
{
auto csp = lastContext.csp;
duint dest = 0;

View File

@ -31,9 +31,9 @@ bool CodeFollowPass::Analyse()
return false;
}
duint CodeFollowPass::GetReferenceOperand(const ZydisDecodedInstruction & Context)
duint CodeFollowPass::GetReferenceOperand(const ZydisDisassembledInstruction & Context)
{
for(int i = 0; i < Context.operandCount; i++)
for(int i = 0; i < Context.info.operand_count; i++)
{
auto operand = Context.operands[i];
@ -50,9 +50,9 @@ duint CodeFollowPass::GetReferenceOperand(const ZydisDecodedInstruction & Contex
return 0;
}
duint CodeFollowPass::GetMemoryOperand(Zydis & Disasm, const ZydisDecodedInstruction & Context, bool* Indirect)
duint CodeFollowPass::GetMemoryOperand(Zydis & Disasm, const ZydisDisassembledInstruction & Context, bool* Indirect)
{
if(Context.operandCount <= 0)
if(Context.info.operand_count <= 0)
return 0;
// Only the first operand matters

View File

@ -14,6 +14,6 @@ public:
virtual bool Analyse() override;
private:
duint GetReferenceOperand(const ZydisDecodedInstruction & Context);
duint GetMemoryOperand(Zydis & Disasm, const ZydisDecodedInstruction & Context, bool* Indirect);
duint GetReferenceOperand(const ZydisDisassembledInstruction & Context);
duint GetMemoryOperand(Zydis & Disasm, const ZydisDisassembledInstruction & Context, bool* Indirect);
};

View File

@ -79,6 +79,7 @@ void AdvancedAnalysis::analyzeFunction(duint entryPoint, bool writedata)
CFGraph graph(entryPoint);
UintSet visited;
std::queue<duint> queue;
visited.reserve(queue.size());
mEntryPoints.insert(entryPoint);
queue.push(graph.entryPoint);
while(!queue.empty())
@ -93,7 +94,7 @@ void AdvancedAnalysis::analyzeFunction(duint entryPoint, bool writedata)
while(true)
{
node.icount++;
if(!mCp.Disassemble(node.end, translateAddr(node.end)))
if(!mZydis.Disassemble(node.end, translateAddr(node.end)))
{
if(writedata)
mEncMap[node.end - mBase] = (byte)enc_byte;
@ -108,7 +109,7 @@ void AdvancedAnalysis::analyzeFunction(duint entryPoint, bool writedata)
}
// If the memory range doesn't fit the entire instruction
// mark it as bytes and finish this node
if(!inRange(node.end + mCp.Size() - 1))
if(!inRange(node.end + mZydis.Size() - 1))
{
duint remainingSize = mBase + mSize - node.end;
memset(&mEncMap[node.end - mBase], (byte)enc_byte, remainingSize);
@ -118,15 +119,15 @@ void AdvancedAnalysis::analyzeFunction(duint entryPoint, bool writedata)
if(writedata)
{
mEncMap[node.end - mBase] = (byte)enc_code;
for(int i = 1; i < mCp.Size(); i++)
for(size_t i = 1; i < mZydis.Size(); i++)
mEncMap[node.end - mBase + i] = (byte)enc_middle;
}
if(mCp.IsJump() || mCp.IsLoop()) //jump
if(mZydis.IsJump() || mZydis.IsLoop()) //jump
{
//set the branch destinations
node.brtrue = mCp.BranchDestination();
if(mCp.GetId() != ZYDIS_MNEMONIC_JMP) //unconditional jumps dont have a brfalse
node.brfalse = node.end + mCp.Size();
node.brtrue = (duint)mZydis.BranchDestination();
if(mZydis.GetId() != ZYDIS_MNEMONIC_JMP) //unconditional jumps dont have a brfalse
node.brfalse = node.end + mZydis.Size();
//add node to the function graph
graph.AddNode(node);
@ -139,26 +140,26 @@ void AdvancedAnalysis::analyzeFunction(duint entryPoint, bool writedata)
break;
}
if(mCp.IsCall()) //call
if(mZydis.IsCall()) //call
{
//TODO: handle no return
duint target = mCp.BranchDestination();
auto target = (duint)mZydis.BranchDestination();
if(inRange(target) && mEntryPoints.find(target) == mEntryPoints.end())
mCandidateEPs.insert(target);
}
if(mCp.IsRet()) //return
if(mZydis.IsRet()) //return
{
node.terminal = true;
graph.AddNode(node);
break;
}
// If this instruction finishes the memory range, end the loop for this entry point
if(!inRange(node.end + mCp.Size()))
if(!inRange(node.end + mZydis.Size()))
{
graph.AddNode(node);
break;
}
node.end += mCp.Size();
node.end += mZydis.Size();
}
}
mFunctions.push_back(graph);
@ -172,20 +173,20 @@ void AdvancedAnalysis::linearXrefPass()
for(auto addr = mBase; addr < mBase + mSize;)
{
if(!mCp.Disassemble(addr, translateAddr(addr)))
if(!mZydis.Disassemble(addr, translateAddr(addr)))
{
addr++;
continue;
}
addr += mCp.Size();
addr += mZydis.Size();
XREF xref;
xref.valid = true;
xref.addr = 0;
xref.from = mCp.Address();
for(auto i = 0; i < mCp.OpCount(); i++)
xref.from = (duint)mZydis.Address();
for(auto i = 0; i < mZydis.OpCount(); i++)
{
duint dest = mCp.ResolveOpValue(i, [](ZydisRegister)->size_t
auto dest = (duint)mZydis.ResolveOpValue(i, [](ZydisRegister) -> uint64_t
{
return 0;
});
@ -197,9 +198,9 @@ void AdvancedAnalysis::linearXrefPass()
}
if(xref.addr)
{
if(mCp.IsCall())
if(mZydis.IsCall())
xref.type = XREF_CALL;
else if(mCp.IsJump())
else if(mZydis.IsJump())
xref.type = XREF_JMP;
else
xref.type = XREF_DATA;
@ -269,16 +270,16 @@ void AdvancedAnalysis::writeDataXrefs()
{
if(xref.type == XREF_DATA && xref.valid)
{
if(!mCp.Disassemble(xref.from, translateAddr(xref.from)))
if(!mZydis.Disassemble(xref.from, translateAddr(xref.from)))
{
xref.valid = false;
continue;
}
auto opcode = mCp.GetId();
auto opcode = mZydis.GetId();
bool isfloat = isFloatInstruction(opcode);
for(auto i = 0; i < mCp.OpCount(); i++)
for(auto i = 0; i < mZydis.OpCount(); i++)
{
auto & op = mCp[i];
auto & op = mZydis[i];
ENCODETYPE type = enc_unknown;
//Todo: Analyze op type and set correct type
@ -344,6 +345,7 @@ void AdvancedAnalysis::writeDataXrefs()
void AdvancedAnalysis::findFuzzyEntryPoints()
{
mCandidateEPs.reserve(mFuzzyEPs.size());
for(const auto & entryPoint : mFuzzyEPs)
{
mCandidateEPs.insert(entryPoint);
@ -392,6 +394,7 @@ void AdvancedAnalysis::analyzeCandidateFunctions(bool writedata)
pendingEPs.clear();
if(mCandidateEPs.size() == 0)
return;
pendingEPs.reserve(mCandidateEPs.size());
for(const auto & entryPoint : mCandidateEPs)
{
pendingEPs.insert(entryPoint);

View File

@ -17,7 +17,7 @@ protected:
duint mBase;
duint mSize;
unsigned char* mData;
Zydis mCp;
Zydis mZydis;
bool inRange(duint addr) const
{

View File

@ -140,26 +140,26 @@ void ControlFlowAnalysis::BasicBlockStarts()
for(duint i = 0; i < mSize;)
{
auto addr = mBase + i;
if(mCp.Disassemble(addr, translateAddr(addr), MAX_DISASM_BUFFER))
if(mZydis.Disassemble(addr, translateAddr(addr), MAX_DISASM_BUFFER))
{
if(bSkipFilling) //handle filling skip mode
{
if(!mCp.IsFilling()) //do nothing until the filling stopped
if(!mZydis.IsFilling()) //do nothing until the filling stopped
{
bSkipFilling = false;
mBlockStarts.insert(addr);
}
}
else if(mCp.IsRet()) //RET breaks control flow
else if(mZydis.IsRet()) //RET breaks control flow
{
bSkipFilling = true; //skip INT3/NOP/whatever filling bytes (those are not part of the control flow)
}
else if(mCp.IsJump() || mCp.IsLoop()) //branches
else if(mZydis.IsJump() || mZydis.IsLoop()) //branches
{
auto dest1 = getReferenceOperand();
duint dest2 = 0;
if(mCp.GetId() != ZYDIS_MNEMONIC_JMP) //conditional jump
dest2 = addr + mCp.Size();
if(mZydis.GetId() != ZYDIS_MNEMONIC_JMP) //conditional jump
dest2 = addr + mZydis.Size();
if(!dest1 && !dest2) //TODO: better code for this (make sure absolutely no filling is inserted)
bSkipFilling = true;
@ -168,7 +168,7 @@ void ControlFlowAnalysis::BasicBlockStarts()
if(dest2)
mBlockStarts.insert(dest2);
}
else if(mCp.IsCall())
else if(mZydis.IsCall())
{
auto dest1 = getReferenceOperand();
if(dest1)
@ -183,7 +183,7 @@ void ControlFlowAnalysis::BasicBlockStarts()
if(dest1)
mBlockStarts.insert(dest1);
}
i += mCp.Size();
i += mZydis.Size();
}
else
i++;
@ -204,23 +204,23 @@ void ControlFlowAnalysis::BasicBlocks()
for(duint addr = start, prevaddr; addr < mBase + mSize;)
{
prevaddr = addr;
if(mCp.Disassemble(addr, translateAddr(addr), MAX_DISASM_BUFFER))
if(mZydis.Disassemble(addr, translateAddr(addr), MAX_DISASM_BUFFER))
{
if(mCp.IsRet())
if(mZydis.IsRet())
{
insertBlock(BasicBlock(start, addr, 0, 0)); //leaf block
break;
}
else if(mCp.IsJump() || mCp.IsLoop())
else if(mZydis.IsJump() || mZydis.IsLoop())
{
auto dest1 = getReferenceOperand();
auto dest2 = mCp.GetId() != ZYDIS_MNEMONIC_JMP ? addr + mCp.Size() : 0;
auto dest2 = mZydis.GetId() != ZYDIS_MNEMONIC_JMP ? addr + mZydis.Size() : 0;
insertBlock(BasicBlock(start, addr, dest1, dest2));
insertParent(dest1, start);
insertParent(dest2, start);
break;
}
addr += mCp.Size();
addr += mZydis.Size();
}
else
addr++;
@ -275,7 +275,7 @@ void ControlFlowAnalysis::Functions()
{
auto function = findFunctionStart(block, parents);
if(!function) //this happens with loops / unreferenced blocks sometimes
delayedBlocks.push_back(DelayedBlock(block, parents));
delayedBlocks.emplace_back(block, parents);
else
block->function = function;
}
@ -413,9 +413,9 @@ String ControlFlowAnalysis::blockToString(const BasicBlock* block)
duint ControlFlowAnalysis::getReferenceOperand() const
{
for(auto i = 0; i < mCp.OpCount(); i++)
for(auto i = 0; i < mZydis.OpCount(); i++)
{
const auto & op = mCp[i];
const auto & op = mZydis[i];
if(op.type == ZYDIS_OPERAND_TYPE_IMMEDIATE)
{
auto dest = duint(op.imm.value.u);
@ -426,7 +426,7 @@ duint ControlFlowAnalysis::getReferenceOperand() const
{
auto dest = duint(op.mem.disp.value);
if(op.mem.base == ZYDIS_REGISTER_RIP) //rip-relative
dest += mCp.Address() + mCp.Size();
dest += (duint)mZydis.Address() + mZydis.Size();
if(inRange(dest))
return dest;
}

View File

@ -45,12 +45,12 @@ void LinearAnalysis::populateReferences()
for(duint i = 0; i < mSize;)
{
auto addr = mBase + i;
if(mCp.Disassemble(addr, translateAddr(addr), MAX_DISASM_BUFFER))
if(mZydis.Disassemble(addr, translateAddr(addr), MAX_DISASM_BUFFER))
{
auto ref = getReferenceOperand();
if(ref)
mFunctions.push_back({ ref, 0 });
i += mCp.Size();
i += mZydis.Size();
}
else
i++;
@ -72,8 +72,8 @@ void LinearAnalysis::analyseFunctions()
auto end = findFunctionEnd(function.start, maxaddr);
if(end)
{
if(mCp.Disassemble(end, translateAddr(end), MAX_DISASM_BUFFER))
function.end = end + mCp.Size() - 1;
if(mZydis.Disassemble(end, translateAddr(end), MAX_DISASM_BUFFER))
function.end = end + mZydis.Size() - 1;
else
function.end = end;
}
@ -83,10 +83,10 @@ void LinearAnalysis::analyseFunctions()
duint LinearAnalysis::findFunctionEnd(duint start, duint maxaddr)
{
//disassemble first instruction for some heuristics
if(mCp.Disassemble(start, translateAddr(start), MAX_DISASM_BUFFER))
if(mZydis.Disassemble(start, translateAddr(start), MAX_DISASM_BUFFER))
{
//JMP [123456] ; import
if(mCp.IsJump() && mCp.OpCount() && mCp[0].type == ZYDIS_OPERAND_TYPE_MEMORY)
if(mZydis.IsJump() && mZydis.OpCount() && mZydis[0].type == ZYDIS_OPERAND_TYPE_MEMORY)
return 0;
}
@ -95,14 +95,14 @@ duint LinearAnalysis::findFunctionEnd(duint start, duint maxaddr)
duint jumpback = 0;
for(duint addr = start, fardest = 0; addr < maxaddr;)
{
if(mCp.Disassemble(addr, translateAddr(addr), MAX_DISASM_BUFFER))
if(mZydis.Disassemble(addr, translateAddr(addr), MAX_DISASM_BUFFER))
{
if(addr + mCp.Size() > maxaddr) //we went past the maximum allowed address
if(addr + mZydis.Size() > maxaddr) //we went past the maximum allowed address
break;
if((mCp.IsJump() || mCp.IsLoop()) && mCp.OpCount() && mCp[0].type == ZYDIS_OPERAND_TYPE_IMMEDIATE) //jump
if((mZydis.IsJump() || mZydis.IsLoop()) && mZydis.OpCount() && mZydis[0].type == ZYDIS_OPERAND_TYPE_IMMEDIATE) //jump
{
auto dest = duint(mCp[0].imm.value.u);
auto dest = duint(mZydis[0].imm.value.u);
if(dest >= maxaddr) //jump across function boundaries
{
@ -112,19 +112,19 @@ duint LinearAnalysis::findFunctionEnd(duint start, duint maxaddr)
{
fardest = dest;
}
else if(end && dest < end && (mCp.GetId() == ZYDIS_MNEMONIC_JMP || mCp.GetId() == ZYDIS_MNEMONIC_LOOP)) //save the last JMP backwards
else if(end && dest < end && (mZydis.GetId() == ZYDIS_MNEMONIC_JMP || mZydis.GetId() == ZYDIS_MNEMONIC_LOOP)) //save the last JMP backwards
{
jumpback = addr;
}
}
else if(mCp.IsRet()) //possible function end?
else if(mZydis.IsRet()) //possible function end?
{
end = addr;
if(fardest < addr) //we stop if the farthest JXX destination forward is before this RET
break;
}
addr += mCp.Size();
addr += mZydis.Size();
}
else
addr++;
@ -134,10 +134,10 @@ duint LinearAnalysis::findFunctionEnd(duint start, duint maxaddr)
duint LinearAnalysis::getReferenceOperand() const
{
for(auto i = 0; i < mCp.OpCount(); i++)
for(auto i = 0; i < mZydis.OpCount(); i++)
{
const auto & op = mCp[i];
if(mCp.IsJump() || mCp.IsLoop()) //skip jumps/loops
const auto & op = mZydis[i];
if(mZydis.IsJump() || mZydis.IsLoop()) //skip jumps/loops
continue;
if(op.type == ZYDIS_OPERAND_TYPE_IMMEDIATE) //we are looking for immediate references
{

View File

@ -59,11 +59,11 @@ void RecursiveAnalysis::SetMarkers()
duint rangeStart = 0, rangeEnd = 0, rangeInstructionCount = 0;
for(auto rangeItr = blockRanges.begin(); rangeItr != blockRanges.end(); ++rangeItr)
{
auto disasmLen = [this](duint addr)
auto disasmLen = [this](duint addr) -> size_t
{
if(!mCp.Disassemble(addr, translateAddr(addr)))
if(!mZydis.Disassemble(addr, translateAddr(addr)))
return 1;
return mCp.Size();
return mZydis.Size();
};
const auto & node = *rangeItr->second;
if(!rangeStart)
@ -149,6 +149,7 @@ void RecursiveAnalysis::analyzeFunction(duint entryPoint)
CFGraph graph(entryPoint);
UintSet visited;
std::queue<duint> queue;
visited.reserve(queue.size());
queue.push(graph.entryPoint);
while(!queue.empty())
{
@ -170,14 +171,14 @@ void RecursiveAnalysis::analyzeFunction(duint entryPoint)
{
if(!inRange(node.end))
{
node.end = mCp.Address();
node.end = (duint)mZydis.Address();
node.terminal = true;
graph.AddNode(node);
break;
}
node.icount++;
if(!mCp.Disassemble(node.end, translateAddr(node.end)))
if(!mZydis.Disassemble(node.end, translateAddr(node.end)))
{
node.end++;
continue;
@ -186,10 +187,10 @@ void RecursiveAnalysis::analyzeFunction(duint entryPoint)
//do xref analysis on the instruction
XREF xref;
xref.addr = 0;
xref.from = mCp.Address();
for(auto i = 0; i < mCp.OpCount(); i++)
xref.from = (duint)mZydis.Address();
for(auto i = 0; i < mZydis.OpCount(); i++)
{
duint dest = mCp.ResolveOpValue(i, [](ZydisRegister)->size_t
auto dest = (duint)mZydis.ResolveOpValue(i, [](ZydisRegister) -> uint64_t
{
return 0;
});
@ -202,23 +203,23 @@ void RecursiveAnalysis::analyzeFunction(duint entryPoint)
if(xref.addr)
mXrefs.push_back(xref);
if(!mCp.IsNop() && (mCp.IsJump() || mCp.IsLoop())) //non-nop jump
if(!mZydis.IsNop() && (mZydis.IsJump() || mZydis.IsLoop())) //non-nop jump
{
//set the branch destinations
node.brtrue = mCp.BranchDestination();
if(mCp.GetId() != ZYDIS_MNEMONIC_JMP) //unconditional jumps dont have a brfalse
node.brfalse = node.end + mCp.Size();
node.brtrue = (duint)mZydis.BranchDestination();
if(mZydis.GetId() != ZYDIS_MNEMONIC_JMP) //unconditional jumps dont have a brfalse
node.brfalse = node.end + mZydis.Size();
//consider register/memory branches as terminal nodes
if(mCp.OpCount() && mCp[0].type != ZYDIS_OPERAND_TYPE_IMMEDIATE)
if(mZydis.OpCount() && mZydis[0].type != ZYDIS_OPERAND_TYPE_IMMEDIATE)
{
//jmp ptr [index * sizeof(duint) + switchTable]
if(mCp[0].type == ZYDIS_OPERAND_TYPE_MEMORY && mCp[0].mem.base == ZYDIS_REGISTER_NONE && mCp[0].mem.index != ZYDIS_REGISTER_NONE
&& mCp[0].mem.scale == sizeof(duint) && MemIsValidReadPtr(duint(mCp[0].mem.disp.value)))