Skip to content

Commit a8d00cb

Browse files
committed
Merged in Dreg_fr33project/x64_dbg (pull request x64dbg#19)
Set Page Memory Rights + JIT improves (fixes and admin check)
2 parents e028ccf + 9dcef6a commit a8d00cb

15 files changed

+739
-39
lines changed

x64_dbg_dbg/_dbgfunctions.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,26 @@ static bool _getjitauto(bool* jit_auto)
112112
return dbggetjitauto(jit_auto, notfound, NULL, NULL);
113113
}
114114

115+
static bool _isprocesselevated(void)
116+
{
117+
return IsProcessElevated();
118+
}
119+
120+
static bool _getpagerights(uint* addr, char* rights)
121+
{
122+
return dbggetpagerights(addr, rights);
123+
}
124+
125+
static bool _pagerightstostring(DWORD protect, char* rights)
126+
{
127+
return dbgpagerightstostring(protect, rights);
128+
}
129+
130+
static bool _setpagerights(uint* addr, char* rights)
131+
{
132+
return dbgsetpagerights(addr, rights);
133+
}
134+
115135
static bool _getjit(char* jit, bool jit64)
116136
{
117137
arch dummy;
@@ -180,4 +200,8 @@ void dbgfunctionsinit()
180200
_dbgfunctions.GetJitAuto = _getjitauto;
181201
_dbgfunctions.GetDefJit = dbggetdefjit;
182202
_dbgfunctions.GetProcessList = _getprocesslist;
203+
_dbgfunctions.GetPageRights = _getpagerights;
204+
_dbgfunctions.SetPageRights = _setpagerights;
205+
_dbgfunctions.PageRightsToString = _pagerightstostring;
206+
_dbgfunctions.IsProcessElevated = _isprocesselevated;
183207
}

x64_dbg_dbg/_dbgfunctions.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ typedef bool (*GETJIT)(char* jit, bool x64);
5757
typedef bool (*GETJITAUTO)(bool*);
5858
typedef bool (*GETDEFJIT)(char*);
5959
typedef bool (*GETPROCESSLIST)(DBGPROCESSINFO** entries, int* count);
60+
typedef bool (*GETPAGERIGHTS)(duint*, char*);
61+
typedef bool (*SETPAGERIGHTS)(duint*, char*);
62+
typedef bool (*PAGERIGHTSTOSTRING)(DWORD, char*);
63+
typedef bool (*ISPROCESSELEVATED)(void);
6064

6165
typedef struct DBGFUNCTIONS_
6266
{
@@ -84,6 +88,10 @@ typedef struct DBGFUNCTIONS_
8488
GETJIT GetJit;
8589
GETDEFJIT GetDefJit;
8690
GETPROCESSLIST GetProcessList;
91+
GETPAGERIGHTS GetPageRights;
92+
SETPAGERIGHTS SetPageRights;
93+
PAGERIGHTSTOSTRING PageRightsToString;
94+
ISPROCESSELEVATED IsProcessElevated;
8795
} DBGFUNCTIONS;
8896

8997
#ifdef BUILD_DBG

x64_dbg_dbg/debugger.cpp

Lines changed: 139 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1480,6 +1480,22 @@ void cbDetach()
14801480
return;
14811481
}
14821482

1483+
1484+
bool IsProcessElevated()
1485+
{
1486+
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
1487+
PSID SecurityIdentifier;
1488+
if(!AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &SecurityIdentifier))
1489+
return 0;
1490+
1491+
BOOL IsAdminMember;
1492+
if(!CheckTokenMembership(NULL, SecurityIdentifier, &IsAdminMember))
1493+
IsAdminMember = FALSE;
1494+
1495+
FreeSid(SecurityIdentifier);
1496+
return IsAdminMember ? true : false;
1497+
}
1498+
14831499
bool _readwritejitkey(char* jit_key_value, DWORD* jit_key_vale_size, char* key, arch arch_in, arch* arch_out, readwritejitkey_error_t* error, bool write)
14841500
{
14851501
DWORD key_flags;
@@ -1491,7 +1507,15 @@ bool _readwritejitkey(char* jit_key_value, DWORD* jit_key_vale_size, char* key,
14911507
* error = ERROR_RW;
14921508

14931509
if(write)
1510+
{
1511+
if(!IsProcessElevated())
1512+
{
1513+
if(error != NULL)
1514+
* error = ERROR_RW_NOTADMIN;
1515+
return false;
1516+
}
14941517
key_flags = KEY_WRITE;
1518+
}
14951519
else
14961520
key_flags = KEY_READ;
14971521

@@ -1512,7 +1536,7 @@ bool _readwritejitkey(char* jit_key_value, DWORD* jit_key_vale_size, char* key,
15121536

15131537
if(arch_in == x64)
15141538
{
1515-
#ifdef _WIN32
1539+
#ifndef _WIN64
15161540
if(!IsWow64())
15171541
{
15181542
if(error != NULL)
@@ -1562,6 +1586,120 @@ bool _readwritejitkey(char* jit_key_value, DWORD* jit_key_vale_size, char* key,
15621586
return true;
15631587
}
15641588

1589+
bool dbgpagerightstostring(DWORD protect, char* rights)
1590+
{
1591+
memset(rights, 0, RIGHTS_STRING);
1592+
1593+
switch(protect & 0xFF)
1594+
{
1595+
case PAGE_EXECUTE:
1596+
strcpy(rights, "E---");
1597+
break;
1598+
case PAGE_EXECUTE_READ:
1599+
strcpy(rights, "ER--");
1600+
break;
1601+
case PAGE_EXECUTE_READWRITE:
1602+
strcpy(rights, "ERW-");
1603+
break;
1604+
case PAGE_EXECUTE_WRITECOPY:
1605+
strcpy(rights, "ERWC");
1606+
break;
1607+
case PAGE_NOACCESS:
1608+
strcpy(rights, "----");
1609+
break;
1610+
case PAGE_READONLY:
1611+
strcpy(rights, "-R--");
1612+
break;
1613+
case PAGE_READWRITE:
1614+
strcpy(rights, "-RW-");
1615+
break;
1616+
case PAGE_WRITECOPY:
1617+
strcpy(rights, "-RWC");
1618+
break;
1619+
}
1620+
1621+
if(protect & PAGE_GUARD)
1622+
strcat(rights, "G");
1623+
else
1624+
strcat(rights, "-");
1625+
1626+
return true;
1627+
}
1628+
1629+
void dbggetpageligned(uint* addr)
1630+
{
1631+
#ifdef _WIN64
1632+
* addr &= 0xFFFFFFFFFFFFF000;
1633+
#else // _WIN32
1634+
* addr &= 0xFFFFF000;
1635+
#endif // _WIN64
1636+
}
1637+
1638+
1639+
bool dbgpagerightsfromstring(DWORD* protect, char* rights_string)
1640+
{
1641+
if(strlen(rights_string) < 2)
1642+
return false;
1643+
1644+
* protect = 0;
1645+
if(rights_string[0] == 'G' || rights_string[0] == 'g')
1646+
{
1647+
* protect |= PAGE_GUARD;
1648+
rights_string++;
1649+
}
1650+
1651+
if(_strcmpi(rights_string, "Execute") == 0)
1652+
* protect |= PAGE_EXECUTE;
1653+
else if(_strcmpi(rights_string, "ExecuteRead") == 0)
1654+
* protect |= PAGE_EXECUTE_READ;
1655+
else if(_strcmpi(rights_string, "ExecuteReadWrite") == 0)
1656+
* protect |= PAGE_EXECUTE_READWRITE;
1657+
else if(_strcmpi(rights_string, "ExecuteWriteCopy") == 0)
1658+
* protect |= PAGE_EXECUTE_WRITECOPY;
1659+
else if(_strcmpi(rights_string, "NoAccess") == 0)
1660+
* protect |= PAGE_NOACCESS;
1661+
else if(_strcmpi(rights_string, "ReadOnly") == 0)
1662+
* protect |= PAGE_READONLY;
1663+
else if(_strcmpi(rights_string, "ReadWrite") == 0)
1664+
* protect |= PAGE_READWRITE;
1665+
else if(_strcmpi(rights_string, "WriteCopy") == 0)
1666+
* protect |= PAGE_WRITECOPY;
1667+
1668+
if(* protect == 0)
1669+
return false;
1670+
1671+
return true;
1672+
}
1673+
1674+
bool dbgsetpagerights(uint* addr, char* rights_string)
1675+
{
1676+
DWORD protect;
1677+
DWORD old_protect;
1678+
1679+
dbggetpageligned(addr);
1680+
1681+
if(!dbgpagerightsfromstring(& protect, rights_string))
1682+
return false;
1683+
1684+
if(VirtualProtectEx(fdProcessInfo->hProcess, (void*)*addr, PAGE_SIZE, protect, & old_protect) == 0)
1685+
return false;
1686+
1687+
// ADD ME: CALL TO UPDATE MEMORY VIEW HERE :-)
1688+
1689+
return true;
1690+
}
1691+
1692+
bool dbggetpagerights(uint* addr, char* rights)
1693+
{
1694+
dbggetpageligned(addr);
1695+
1696+
MEMORY_BASIC_INFORMATION mbi;
1697+
if(VirtualQueryEx(fdProcessInfo->hProcess, (const void*)*addr, &mbi, sizeof(mbi)) == 0)
1698+
return false;
1699+
1700+
return dbgpagerightstostring(mbi.Protect, rights);
1701+
}
1702+
15651703
bool dbggetjitauto(bool* auto_on, arch arch_in, arch* arch_out, readwritejitkey_error_t* rw_error_out)
15661704
{
15671705
char jit_entry[4];

x64_dbg_dbg/debugger.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@
1010
#define JIT_ENTRY_DEF_SIZE (MAX_PATH + sizeof(ATTACH_CMD_LINE) + 2)
1111
#define JIT_ENTRY_MAX_SIZE 512
1212
#define JIT_REG_KEY TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug")
13+
#define RIGHTS_STRING (sizeof("ERWCG") + 1)
1314

1415
typedef enum
1516
{
1617
ERROR_RW = 0,
1718
ERROR_RW_FILE_NOT_FOUND,
18-
ERROR_RW_NOTWOW64
19+
ERROR_RW_NOTWOW64,
20+
ERROR_RW_NOTADMIN
1921
} readwritejitkey_error_t;
2022

2123
//structures
@@ -62,12 +64,18 @@ bool dbgisignoredexception(unsigned int exception);
6264
bool dbgcmdnew(const char* name, CBCOMMAND cbCommand, bool debugonly);
6365
bool dbgcmddel(const char* name);
6466
bool dbggetjit(char jit_entry[JIT_ENTRY_MAX_SIZE], arch arch_in, arch* arch_out, readwritejitkey_error_t*);
67+
bool dbggetpagerights(uint*, char*);
68+
bool dbgpagerightstostring(DWORD, char*);
69+
void dbggetpageligned(uint*);
70+
bool dbgpagerightsfromstring(DWORD*, char*);
71+
bool dbgsetpagerights(uint*, char*);
6572
bool dbgsetjit(char* jit_cmd, arch arch_in, arch* arch_out, readwritejitkey_error_t*);
6673
bool dbggetdefjit(char* jit_entry);
6774
bool _readwritejitkey(char*, DWORD*, char*, arch, arch*, readwritejitkey_error_t*, bool);
6875
bool dbggetjitauto(bool*, arch, arch*, readwritejitkey_error_t*);
6976
bool dbgsetjitauto(bool, arch, arch*, readwritejitkey_error_t*);
7077
bool dbglistprocesses(std::vector<PROCESSENTRY32>* list);
78+
bool IsProcessElevated();
7179

7280
void cbStep();
7381
void cbRtrStep();

x64_dbg_dbg/debugger_commands.cpp

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1437,6 +1437,11 @@ CMDRESULT cbDebugSetJITAuto(int argc, char* argv[])
14371437
{
14381438
arch actual_arch;
14391439
bool set_jit_auto;
1440+
if(!IsProcessElevated())
1441+
{
1442+
dprintf("Error run the debugger as Admin to setjitauto\n");
1443+
return STATUS_ERROR;
1444+
}
14401445
if(argc < 2)
14411446
{
14421447
dprintf("Error setting JIT Auto. Use ON:1 or OFF:0 arg or x64/x32, ON:1 or OFF:0.\n");
@@ -1512,6 +1517,11 @@ CMDRESULT cbDebugSetJIT(int argc, char* argv[])
15121517
arch actual_arch;
15131518
char* jit_debugger_cmd;
15141519
char oldjit[MAX_SETTING_SIZE] = "";
1520+
if(!IsProcessElevated())
1521+
{
1522+
dprintf("Error run the debugger as Admin to setjit\n");
1523+
return STATUS_ERROR;
1524+
}
15151525
if(argc < 2)
15161526
{
15171527
char path[JIT_ENTRY_DEF_SIZE];
@@ -1619,7 +1629,7 @@ CMDRESULT cbDebugSetJIT(int argc, char* argv[])
16191629
if(rw_error == ERROR_RW_NOTWOW64)
16201630
dprintf("Error using x64 arg. The debugger is not a WOW64 process\n");
16211631
else
1622-
dprintf("Error getting JIT %s\n", (actual_arch == x64) ? "x64" : "x32");
1632+
dprintf("Error setting JIT %s\n", (actual_arch == x64) ? "x64" : "x32");
16231633
return STATUS_ERROR;
16241634
}
16251635
}
@@ -1686,5 +1696,55 @@ CMDRESULT cbDebugGetJIT(int argc, char* argv[])
16861696

16871697
dprintf("JIT %s: %s\n", (actual_arch == x64) ? "x64" : "x32", get_entry);
16881698

1699+
return STATUS_CONTINUE;
1700+
}
1701+
1702+
CMDRESULT cbDebugGetPageRights(int argc, char* argv[])
1703+
{
1704+
uint addr = 0;
1705+
char rights[RIGHTS_STRING];
1706+
1707+
if(argc != 2 || !valfromstring(argv[1], &addr))
1708+
{
1709+
dprintf("Error: using an address as arg1\n");
1710+
return STATUS_ERROR;
1711+
}
1712+
1713+
if(!dbggetpagerights(&addr, rights))
1714+
{
1715+
dprintf("Error getting rights of page: %s\n", argv[1]);
1716+
return STATUS_ERROR;
1717+
}
1718+
1719+
dprintf("Page: "fhex", Rights: %s\n", addr, rights);
1720+
1721+
return STATUS_CONTINUE;
1722+
}
1723+
1724+
CMDRESULT cbDebugSetPageRights(int argc, char* argv[])
1725+
{
1726+
uint addr = 0;
1727+
char rights[RIGHTS_STRING];
1728+
1729+
if(argc != 3 || !valfromstring(argv[1], &addr))
1730+
{
1731+
dprintf("Error: using an address as arg1 and as arg2: Execute, ExecuteRead, ExecuteReadWrite, ExecuteWriteCopy, NoAccess, ReadOnly, ReadWrite, WriteCopy. You can add a G at first for add PAGE GUARD, example: GReadOnly\n");
1732+
return STATUS_ERROR;
1733+
}
1734+
1735+
if(!dbgsetpagerights(&addr, argv[2]))
1736+
{
1737+
dprintf("Error: Set rights of "fhex" with Rights: %s\n", addr, argv[2]);
1738+
return STATUS_ERROR;
1739+
}
1740+
1741+
if(!dbggetpagerights(&addr, rights))
1742+
{
1743+
dprintf("Error getting rights of page: %s\n", argv[1]);
1744+
return STATUS_ERROR;
1745+
}
1746+
1747+
dprintf("New rights of "fhex": %s\n", addr, rights);
1748+
16891749
return STATUS_CONTINUE;
16901750
}

x64_dbg_dbg/debugger_commands.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,7 @@ CMDRESULT cbDebugDisableHardwareBreakpoint(int argc, char* argv[]);
5555
CMDRESULT cbDebugEnableMemoryBreakpoint(int argc, char* argv[]);
5656
CMDRESULT cbDebugDisableMemoryBreakpoint(int argc, char* argv[]);
5757
CMDRESULT cbDebugDownloadSymbol(int argc, char* argv[]);
58+
CMDRESULT cbDebugGetPageRights(int argc, char* argv[]);
59+
CMDRESULT cbDebugSetPageRights(int argc, char* argv[]);
5860

5961
#endif //_DEBUGGER_COMMANDS_H

x64_dbg_dbg/x64_dbg.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,8 @@ static void registercommands()
162162
dbgcmdnew("alloc", cbDebugAlloc, true); //allocate memory
163163
dbgcmdnew("free", cbDebugFree, true); //free memory
164164
dbgcmdnew("Fill\1memset", cbDebugMemset, true); //memset
165+
dbgcmdnew("getpagerights\1getrightspage", cbDebugGetPageRights, true);
166+
dbgcmdnew("setpagerights\1setrightspage", cbDebugSetPageRights, true);
165167

166168
//plugins
167169
dbgcmdnew("StartScylla\1scylla\1imprec", cbDebugStartScylla, false); //start scylla

0 commit comments

Comments
 (0)