/*
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
*
* Subject to the condition set forth below, permission is hereby granted to
* any person obtaining a copy of this software, associated documentation
* and/or data (collectively the "Software"), free of charge and under any
* and all copyright rights in the Software, and any and all patent rights
* owned or freely licensable by each licensor hereunder covering either (i)
* the unmodified Software as contributed to or provided by such licensor,
* or (ii) the Larger Works (as defined below), to deal in both
*
* (a) the Software, and
*
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file
* if one is included with the Software (each a "Larger Work" to which the
* Software is contributed by such licensors),
*
* without restriction, including without limitation the rights to copy,
* create derivative works of, display, perform, and distribute the Software
* and make, use, sell, offer for sale, import, export, have made, and have
* sold the Software and the Larger Work(s), and to sublicense the foregoing
* rights on either these or other terms.
*
* This license is subject to the following condition:
*
* The above copyright notice and either this complete permission notice or
* at a minimum a reference to the UPL must be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
* NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
/* hsdis.c -- dump a range of addresses as native instructions
This implements the plugin protocol required by the
HotSpot PrintAssembly option.
*/
#include <inttypes.h>
#include <string.h>
#include <capstone.h>
#include "hsdis.h"
/* short names for stuff in hsdis.h */
typedef decode_instructions_event_callback_ftype event_callback_t;
typedef decode_instructions_printf_callback_ftype printf_callback_t;
#define print(...) (*printf_callback) (printf_stream, __VA_ARGS__)
static void* null_event_callback(void* ignore_stream, const char* ignore_event, void* arg) {
return NULL;
}
/* print all events as XML markup */
static void* xml_event_callback(void* stream, const char* event, void* arg) {
FILE* fp = (FILE*) stream;
#define NS_PFX "dis:"
if (event[0] != '/') {
/* issue the tag, with or without a formatted argument */
fprintf(fp, "<"NS_PFX);
fprintf(fp, event, arg);
fprintf(fp, ">");
} else {
++event; /* skip slash */
fprintf(fp, ""NS_PFX"%s>", event);
}
return NULL;
}
static const char* INTEL_SYNTAX_OP = "intel";
typedef struct {
bool intel_syntax;
} Options;
static Options parse_options(const char* options, printf_callback_t printf_callback, void* printf_stream) {
Options ops;
// initialize with defaults
ops.intel_syntax = false;
const char* cursor = options;
while (*cursor != '\0') {
if (*cursor == ',') {
cursor++;
}
if (strncmp(cursor, INTEL_SYNTAX_OP, strlen(INTEL_SYNTAX_OP)) == 0) {
cursor += strlen(INTEL_SYNTAX_OP);
ops.intel_syntax = true;
} else {
const char* end = strchr(cursor, ',');
if (end == NULL) {
end = strchr(cursor, '\0');
}
print("Unknown PrintAssembly option: %.*s\n", (int) (end - cursor), cursor);
cursor = end;
}
}
return ops;
}
#ifdef _WIN32
__declspec(dllexport)
#endif
void* decode_instructions_virtual(uintptr_t start_va, uintptr_t end_va,
unsigned char* buffer, uintptr_t length,
event_callback_t event_callback,
void* event_stream,
printf_callback_t printf_callback,
void* printf_stream,
const char* options,
int newline /* bool value for nice new line */) {
csh cs_handle;
if (printf_callback == NULL) {
int (*fprintf_callback)(FILE*, const char*, ...) = &fprintf;
FILE* fprintf_stream = stdout;
printf_callback = (printf_callback_t) fprintf_callback;
if (printf_stream == NULL)
printf_stream = (void*) fprintf_stream;
}
if (event_callback == NULL) {
if (event_stream == NULL)
event_callback = &null_event_callback;
else
event_callback = &xml_event_callback;
}
if (cs_open(CAPSTONE_ARCH, CAPSTONE_MODE, &cs_handle) != CS_ERR_OK) {
print("Could not open cs_handle");
return NULL;
}
Options ops = parse_options(options, printf_callback, printf_stream);
cs_option(cs_handle, CS_OPT_SYNTAX, ops.intel_syntax ? CS_OPT_SYNTAX_INTEL : CS_OPT_SYNTAX_ATT);
cs_insn *insn;
size_t count = cs_disasm(cs_handle, buffer, length, (uintptr_t) buffer, 0 , &insn);
if (count) {
for (unsigned int j = 0; j < count; j++) {
(*event_callback)(event_stream, "insn", (void*) insn[j].address);
print("%s\t\t%s", insn[j].mnemonic, insn[j].op_str);
(*event_callback)(event_stream, "/insn", (void*) (insn[j].address + insn[j].size));
if (newline) {
/* follow each complete insn by a nice newline */
print("\n");
}
}
cs_free(insn, count);
}
cs_close(&cs_handle);
return NULL;
}
¤ Dauer der Verarbeitung: 0.23 Sekunden
(vorverarbeitet)
¤
|
Haftungshinweis
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.
|