#include "APIHelp.h" #include "NativeAPI.h" #include "NativeStdString.h" #include //////////////////// NativePointer //////////////////// ClassDefine NativePointerBuilder = defineClass("NativePointer") .constructor(nullptr) .function("fromSymbol", &NativePointer::fromSymbol) .function("fromAddress", &NativePointer::fromAddress) .function("malloc",&NativePointer::mallocMem) .function("free", &NativePointer::freeMem) .instanceFunction("asRawAddress", &NativePointer::asRawAddress) .instanceFunction("asHexAddress", &NativePointer::asHexAddress) .instanceFunction("asRef", &NativePointer::asRef) .instanceFunction("deRef", &NativePointer::deRef) .instanceFunction("isNull", &NativePointer::isNull) .instanceFunction("offset", &NativePointer::offset) .instanceProperty("byte", &NativePointer::getMemByte, &NativePointer::setMemByte) .instanceProperty("int8", &NativePointer::getChar, &NativePointer::setChar) .instanceProperty("uint8", &NativePointer::getUchar, &NativePointer::setUchar) .instanceProperty("int16", &NativePointer::getShort, &NativePointer::setShort) .instanceProperty("uint16", &NativePointer::getUshort, &NativePointer::setUshort) .instanceProperty("int32", &NativePointer::getInt, &NativePointer::setInt) .instanceProperty("uint32", &NativePointer::getUint, &NativePointer::setUint) .instanceProperty("long", &NativePointer::getLong, &NativePointer::setLong) .instanceProperty("ulong", &NativePointer::getUlong, &NativePointer::setUlong) .instanceProperty("int64", &NativePointer::getLonglong, &NativePointer::setLonglong) .instanceProperty("uint64", &NativePointer::getUlonglong, &NativePointer::setUlonglong) .instanceProperty("float", &NativePointer::getFloat, &NativePointer::setFloat) .instanceProperty("double", &NativePointer::getDouble, &NativePointer::setDouble) .instanceProperty("string", &NativePointer::getString, &NativePointer::setString) .instanceProperty("bool", &NativePointer::getBool, &NativePointer::setBool) .instanceFunction("asStdString", &NativePointer::asStdString) .build(); NativePointer::NativePointer(void* p) : ScriptClass(ScriptClass::ConstructFromCpp{}) { set(p); } Local NativePointer::fromAddress(const Arguments& args) { CHECK_ARGS_COUNT(args, 1); if (args[0].isString() ){ stringstream ss; ss << hex << args[0].asString().toString(); uintptr_t res; ss >> res; return newNativePointer((void*)res); } else if (args[0].isNumber()) { return newNativePointer((void*)args[0].asNumber().toInt64()); } LOG_WRONG_ARG_TYPE(); return Local(); } Local NativePointer::fromSymbol(const Arguments& args) { CHECK_ARGS_COUNT(args, 1); CHECK_ARG_TYPE(args[0], ValueKind::kString); return newNativePointer(dlsym_real(args[0].asString().toStringHolder().c_str())); } Local NativePointer::mallocMem(const Arguments& args) { CHECK_ARGS_COUNT(args, 1); CHECK_ARG_TYPE(args[0], ValueKind::kNumber); size_t size = args[0].asNumber().toInt64(); return newNativePointer(malloc(size)); } // directly free memblock in c runtime Local NativePointer::freeMem(const Arguments& args) { void* memObj = nullptr; CHECK_ARGS_COUNT(args, 1); if (args[0].isObject()) { memObj = NativePointer::extract(args[0]); } else if (args[0].isNumber()) { *((__int64*)&memObj) = args[0].asNumber().toInt64(); } if (!memObj) { throw std::runtime_error("free(nullptr)"); } free(memObj); return Local(); } Local NativePointer::newNativePointer(void* ptr) { auto out = new NativePointer(ptr); return out->getScriptObject(); } void* NativePointer::extract(Local v) { if (EngineScope::currentEngine()->isInstanceOf(v)) return EngineScope::currentEngine()->getNativeInstance(v)->get(); else return nullptr; } Local NativePointer::asRawAddress(const Arguments& args) { try { void* pkt = unwrap(); if (!pkt) return Local(); return Number::newNumber((intptr_t)pkt); } CATCH("Fail in NativePointer::asPointer!") } Local NativePointer::asHexAddress(const Arguments& args) { try { void* pkt = unwrap(); if (!pkt) return Local(); std::stringstream ss; ss << std::hex << (intptr_t)pkt; return String::newString(ss.str()); } CATCH("Fail in NativePointer::asHexStr!") } Local NativePointer::asRef(const Arguments& args) { try { return newNativePointer((void*)&mPtr); } CATCH("Fail in NativePointer::asRef!") } Local NativePointer::deRef(const Arguments& args) { try { return newNativePointer(*(void**)mPtr); } CATCH("Fail in NativePointer::deRef!") } Local NativePointer::isNull(const Arguments& args) { try { return script::Boolean::newBoolean(mPtr == nullptr); } CATCH("Fail in NativePointer::isNull!") } Local NativePointer::offset(const Arguments& args) { CHECK_ARGS_COUNT(args, 1); CHECK_ARG_TYPE(args[0], ValueKind::kNumber); try { auto ptr = get(); if (!ptr) return Local(); return newNativePointer((void*)((uintptr_t)ptr + args[0].asNumber().toInt32())); } CATCH("Fail in NativePointer::offset!") } Local NativePointer::getMemByte() { try { auto ptr = get(); if (!ptr) return Local(); std::vector buffer(1); ModUtils::MemCopy((uintptr_t)&buffer[0], (uintptr_t)ptr, buffer.size()); uint8_t em = buffer[0]; stringstream ss; ss << hex << int(em); return String::newString(ss.str()); } CATCH("Fail in NativePointer::getMemByte!") } void NativePointer::setMemByte(const Local& value) { try { ModUtils::MemSet((uintptr_t)get(), (unsigned char)stoul(value.asString().toString(), nullptr, 16), 1); } catch (...) { logger.error("Fail to set mem!"); logger.error("In Plugin: " + ENGINE_OWN_DATA()->pluginName); } } Local NativePointer::getChar() { try { return Number::newNumber(*(char*)get()); } CATCH("Fail in NativePointer::getChar!") } void NativePointer::setChar(const Local& value) { try { *(char*)get() = (char)value.asNumber().toInt32(); } catch (...) { logger.error("Fail to set char!"); logger.error("In Plugin: " + ENGINE_OWN_DATA()->pluginName); } } Local NativePointer::getUchar() { try { return Number::newNumber(*(unsigned char*)get()); } CATCH("Fail in NativePointer::getUchar!") } void NativePointer::setUchar(const Local& value) { try { *(unsigned char*)get() = (unsigned char)value.asNumber().toInt32(); } catch (...) { logger.error("Fail to set uchar!"); logger.error("In Plugin: " + ENGINE_OWN_DATA()->pluginName); } } Local NativePointer::getShort() { try { return Number::newNumber(*(short*)get()); } CATCH("Fail in NativePointer::getShort!") } void NativePointer::setShort(const Local& value) { try { *(short*)get() = (short)value.asNumber().toInt32(); } catch (...) { logger.error("Fail to set short!"); logger.error("In Plugin: " + ENGINE_OWN_DATA()->pluginName); } } Local NativePointer::getUshort() { try { return Number::newNumber(*(unsigned short*)get()); } CATCH("Fail in NativePointer::getUshort!") } void NativePointer::setUshort(const Local& value) { try { *(unsigned short*)get() = (unsigned short)value.asNumber().toInt32(); } catch (...) { logger.error("Fail to set ushort!"); logger.error("In Plugin: " + ENGINE_OWN_DATA()->pluginName); } } Local NativePointer::getInt() { try { return Number::newNumber(*(int*)get()); } CATCH("Fail in NativePointer::getInt!") } void NativePointer::setInt(const Local& value) { try { *(int*)get() = (int)value.asNumber().toInt32(); } catch (...) { logger.error("Fail to set int!"); logger.error("In Plugin: " + ENGINE_OWN_DATA()->pluginName); } } Local NativePointer::getUint() { try { return Number::newNumber(*(long long*)get()); } CATCH("Fail in NativePointer::getUint!") } void NativePointer::setUint(const Local& value) { try { *(unsigned int*)get() = (unsigned int)value.asNumber().toInt64(); } catch (...) { logger.error("Fail to set uint!"); logger.error("In Plugin: " + ENGINE_OWN_DATA()->pluginName); } } Local NativePointer::getLong() { try { return Number::newNumber(*(long long*)get()); } CATCH("Fail in NativePointer::getLong!") } void NativePointer::setLong(const Local& value) { try { *(long*)get() = (long)value.asNumber().toInt64(); } catch (...) { logger.error("Fail to set long!"); logger.error("In Plugin: " + ENGINE_OWN_DATA()->pluginName); } } Local NativePointer::getUlong() { try { return Number::newNumber(*(long long*)get()); } CATCH("Fail in NativePointer::getUlong!") } void NativePointer::setUlong(const Local& value) { try { *(unsigned long*)get() = (unsigned long)value.asNumber().toInt64(); } catch (...) { logger.error("Fail to set ulong!"); logger.error("In Plugin: " + ENGINE_OWN_DATA()->pluginName); } } Local NativePointer::getLonglong() { try { return Number::newNumber(*(long long*)get()); } CATCH("Fail in NativePointer::getLonglong!") } void NativePointer::setLonglong(const Local& value) { try { *(long long*)get() = (long long)value.asNumber().toInt64(); } catch (...) { logger.error("Fail to set longlong!"); logger.error("In Plugin: " + ENGINE_OWN_DATA()->pluginName); } } Local NativePointer::getUlonglong() { try { return Number::newNumber(*(long long*)get()); } CATCH("Fail in NativePointer::getUlonglong!") } void NativePointer::setUlonglong(const Local& value) { try { *(unsigned long long*)get() = (unsigned long long)value.asNumber().toInt64(); } catch (...) { logger.error("Fail to set ulonglong!"); logger.error("In Plugin: " + ENGINE_OWN_DATA()->pluginName); } } Local NativePointer::getFloat() { try { return Number::newNumber(*(float*)get()); } CATCH("Fail in NativePointer::getFloat!") } void NativePointer::setFloat(const Local& value) { try { *(float*)get() = (float)value.asNumber().toFloat(); } catch (...) { logger.error("Fail to set float!"); logger.error("In Plugin: " + ENGINE_OWN_DATA()->pluginName); } } Local NativePointer::getDouble() { try { return Number::newNumber(*(double*)get()); } CATCH("Fail in NativePointer::getDouble!") } void NativePointer::setDouble(const Local& value) { try { *(double*)get() = (double)value.asNumber().toFloat(); } catch (...) { logger.error("Fail to set double!"); logger.error("In Plugin: " + ENGINE_OWN_DATA()->pluginName); } } Local NativePointer::getString() { try { return String::newString(*(string*)get()); } CATCH("Fail in NativePointer::getString!") } void NativePointer::setString(const Local& value) { try { *(string*)get() = value.asString().toString(); } catch (...) { logger.error("Fail to set string!"); logger.error("In Plugin: " + ENGINE_OWN_DATA()->pluginName); } } Local NativePointer::getBool() { try { return Boolean::newBoolean(*(bool*)get()); } CATCH("Fail in NativePointer::getBool!") } void NativePointer::setBool(const Local& value) { try { *(bool*)get() = value.asBoolean().value(); } catch (...) { logger.error("Fail to set bool!"); logger.error("In Plugin: " + ENGINE_OWN_DATA()->pluginName); } } Local NativePointer::asStdString() { try { return NativeStdString::newNativeStdString((std::string*)mPtr); } CATCH("Fail in NativePointer::asStdString!") }