add port e9 hack support for all rings (#64)
By enabling the 'all_rings' option, you can utilize the port e9 hack from ring3 IMO very useful for: - user-mode sandbox (ex Cuckoo) - malware analysis - API/SYSCALL logger with a simple hook from ring3 - automation + instrumentation from user mode code - ... So yes, from this PR a user-mode-sandbox can display on the console of the system running Bochs anything that is written to 0xE9 port ![porte9hackallrings](https://github.com/bochs-emu/Bochs/assets/9882181/ddbca3fa-729b-4a3e-95ad-078e44c7a17a) **This PR is 100% backward compatibility** btw, @stlintel I'm not certain if **bochs/config.cc** is the ideal location to define **bool port_e9_hack_all_rings** (unmapped io/dev is better?)
This commit is contained in:
parent
253882589d
commit
da43cc4580
@ -1310,10 +1310,12 @@ speaker: enabled=1, mode=sound, volume=15
|
||||
# very early when writing BIOS or OS code for example, without having to
|
||||
# bother with setting up a serial port or etc. Reading from port 0xE9 will
|
||||
# will return 0xe9 to let you know if the feature is available.
|
||||
# Leave this 0 unless you have a reason to use it.
|
||||
# Leave this 0 unless you have a reason to use it. By enabling the
|
||||
# 'all_rings' option, you can utilize the port e9 hack from ring3.
|
||||
#
|
||||
# Example:
|
||||
# port_e9_hack: enabled=1
|
||||
# port_e9_hack: enabled=1, all_rings=1
|
||||
#=======================================================================
|
||||
#port_e9_hack: enabled=1
|
||||
|
||||
|
@ -285,6 +285,7 @@ sound
|
||||
|
||||
misc
|
||||
port_e9_hack
|
||||
port_e9_hack_all_rings
|
||||
gdbstub
|
||||
port
|
||||
text_base
|
||||
|
@ -1679,6 +1679,13 @@ void bx_init_options()
|
||||
"Debug messages written to i/o port 0xE9 will be displayed on console",
|
||||
0);
|
||||
|
||||
// port e9 hack all rings
|
||||
new bx_param_bool_c(misc,
|
||||
"port_e9_hack_all_rings",
|
||||
"Enable port 0xE9 hack for all rings",
|
||||
"Debug messages written to i/o port 0xE9 from ring3 will be displayed on console",
|
||||
0);
|
||||
|
||||
// GDB stub
|
||||
menu = new bx_list_c(misc, "gdbstub", "GDB Stub Options");
|
||||
menu->set_options(menu->SHOW_PARENT | menu->USE_BOX_TITLE);
|
||||
@ -1763,6 +1770,7 @@ void bx_init_options()
|
||||
misc->add(SIM->get_param(BXPN_KBD_PASTE_DELAY));
|
||||
misc->add(SIM->get_param(BXPN_USER_SHORTCUT));
|
||||
misc->add(SIM->get_param(BXPN_PORT_E9_HACK));
|
||||
misc->add(SIM->get_param(BXPN_PORT_E9_HACK_ALL_RINGS));
|
||||
misc->set_options(misc->SHOW_PARENT | misc->SHOW_GROUP_NAME);
|
||||
}
|
||||
|
||||
@ -2237,6 +2245,30 @@ static int parse_param_bool(const char *input, int len, const char *param)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int parse_port_e9_hack(const char *context, const char **params, int num_params)
|
||||
{
|
||||
if (num_params > 2) {
|
||||
PARSE_ERR(("%s: port_e9_hack directive: wrong # args.", context));
|
||||
}
|
||||
if (strncmp(params[0], "enabled=", 8)) {
|
||||
PARSE_ERR(("%s: port_e9_hack directive malformed.", context));
|
||||
}
|
||||
if (parse_param_bool(params[0], 8, BXPN_PORT_E9_HACK) < 0) {
|
||||
PARSE_ERR(("%s: port_e9_hack directive malformed.", context));
|
||||
}
|
||||
if (num_params == 2) {
|
||||
if (!strncmp(params[1], "all_rings=", 10)) {
|
||||
if (parse_param_bool(params[1], 10, BXPN_PORT_E9_HACK_ALL_RINGS) < 0) {
|
||||
PARSE_ERR(("%s: all_rings option malformed.", context));
|
||||
}
|
||||
} else {
|
||||
PARSE_ERR(("%s: port_e9_hack: invalid parameter %s", context, params[1]));
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bx_parse_param_from_list(const char *context, const char *input, bx_list_c *list)
|
||||
{
|
||||
char *propval, *property, *value;
|
||||
@ -3186,14 +3218,8 @@ static int parse_line_formatted(const char *context, int num_params, char *param
|
||||
PARSE_ERR(("%s: print_timestamps directive malformed.", context));
|
||||
}
|
||||
} else if (!strcmp(params[0], "port_e9_hack")) {
|
||||
if (num_params != 2) {
|
||||
PARSE_ERR(("%s: port_e9_hack directive: wrong # args.", context));
|
||||
}
|
||||
if (strncmp(params[1], "enabled=", 8)) {
|
||||
PARSE_ERR(("%s: port_e9_hack directive malformed.", context));
|
||||
}
|
||||
if (parse_param_bool(params[1], 8, BXPN_PORT_E9_HACK) < 0) {
|
||||
PARSE_ERR(("%s: port_e9_hack directive malformed.", context));
|
||||
if (parse_port_e9_hack(context, (const char **)(params + 1), num_params - 1) < 0) {
|
||||
return -1;
|
||||
}
|
||||
} else if (!strcmp(params[0], "load32bitOSImage")) {
|
||||
PARSE_ERR(("%s: load32bitOSImage: This legacy feature is no longer supported.", context));
|
||||
@ -3550,6 +3576,7 @@ int bx_write_configuration(const char *rc, int overwrite)
|
||||
fprintf(fp, "print_timestamps: enabled=%d\n", bx_dbg.print_timestamps);
|
||||
bx_write_debugger_options(fp);
|
||||
fprintf(fp, "port_e9_hack: enabled=%d\n", SIM->get_param_bool(BXPN_PORT_E9_HACK)->get());
|
||||
fprintf(fp, "port_e9_hack_all_rings: enabled=%d\n", SIM->get_param_bool(BXPN_PORT_E9_HACK_ALL_RINGS)->get());
|
||||
fprintf(fp, "private_colormap: enabled=%d\n", SIM->get_param_bool(BXPN_PRIVATE_COLORMAP)->get());
|
||||
#if BX_WITH_AMIGAOS
|
||||
fprintf(fp, "fullscreen: enabled=%d\n", SIM->get_param_bool(BXPN_FULLSCREEN)->get());
|
||||
|
@ -864,6 +864,10 @@ bool BX_CPP_AttrRegparmN(3) BX_CPU_C::allow_io(bxInstruction_c *i, Bit16u port,
|
||||
/* If CPL <= IOPL, then all IO portesses are accessible.
|
||||
* Otherwise, must check the IO permission map on >286.
|
||||
* On the 286, there is no IO permissions map */
|
||||
|
||||
static bool port_e9_hack_all_rings = SIM->get_param_bool(BXPN_PORT_E9_HACK_ALL_RINGS)->get();
|
||||
if (0xe9 == port && port_e9_hack_all_rings)
|
||||
return(1); // port e9 hack can be used by unprivileged code
|
||||
|
||||
if (BX_CPU_THIS_PTR cr0.get_PE() && (BX_CPU_THIS_PTR get_VM() || (CPL > BX_CPU_THIS_PTR get_IOPL())))
|
||||
{
|
||||
|
@ -5204,13 +5204,17 @@ Example:
|
||||
<screen>
|
||||
port_e9_hack: enabled=1
|
||||
</screen>
|
||||
<screen>
|
||||
port_e9_hack: enabled=1, all_rings=1
|
||||
</screen>
|
||||
The 0xE9 port doesn't exists in normal ISA architecture. However, we
|
||||
define a convention here, to display on the console of the system running
|
||||
Bochs anything that is written to it. The idea is to provide debug output
|
||||
very early when writing BIOS or OS code for example, without having to
|
||||
bother with setting up a serial port or etc. Reading from port 0xE9 will
|
||||
will return 0xe9 to let you know if the feature is available. Leave
|
||||
this 0 unless you have a reason to use it.
|
||||
this 0 unless you have a reason to use it. By enabling the 'all_rings'
|
||||
option, you can utilize the port e9 hack from ring3.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
|
@ -175,6 +175,7 @@
|
||||
#define BXPN_SOUND_SB16 "sound.sb16"
|
||||
#define BXPN_SOUND_ES1370 "sound.es1370"
|
||||
#define BXPN_PORT_E9_HACK "misc.port_e9_hack"
|
||||
#define BXPN_PORT_E9_HACK_ALL_RINGS "misc.port_e9_hack_all_rings"
|
||||
#define BXPN_GDBSTUB "misc.gdbstub"
|
||||
#define BXPN_LOG_FILENAME "log.filename"
|
||||
#define BXPN_LOG_PREFIX "log.prefix"
|
||||
|
Loading…
Reference in New Issue
Block a user