Browse Source

console: add file and memory editor

pull/1/head
BlackINT3 6 years ago
parent
commit
2b032c1980
  1. 1
      .gitattributes
  2. 1
      src/OpenArk/OpenArk.vcxproj
  3. 1
      src/OpenArk/OpenArk.vcxproj.filters
  4. 102
      src/OpenArk/cmds/cmds.cpp
  5. 3
      src/OpenArk/cmds/cmds.h
  6. 7
      src/OpenArk/common/app/app.cpp
  7. 4
      src/OpenArk/common/app/app.h
  8. 6
      src/OpenArk/common/cpp-wrapper/cpp-wrapper.cpp
  9. 3
      src/OpenArk/common/cpp-wrapper/cpp-wrapper.h
  10. 89
      src/OpenArk/common/win-wrapper/win-wrapper.cpp
  11. 2
      src/OpenArk/common/win-wrapper/win-wrapper.h
  12. 3
      src/OpenArkDrv/OpenArkDrv.vcxproj
  13. 3
      src/OpenArkDrv/OpenArkDrv.vcxproj.filters

1
.gitattributes

@ -0,0 +1 @@
*.c linguist-language=C++

1
src/OpenArk/OpenArk.vcxproj

@ -399,6 +399,7 @@
</ItemGroup>
<ItemGroup>
<None Include="openark_zh.ts" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">

1
src/OpenArk/OpenArk.vcxproj.filters

@ -423,6 +423,7 @@
<None Include="openark_zh.ts">
<Filter>Translation Files</Filter>
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<QtRcc Include="res\openark.qrc">

102
src/OpenArk/cmds/cmds.cpp

@ -15,6 +15,7 @@
****************************************************************************/
#include "cmds.h"
#include "constants/constants.h"
#include "../common/utils/disassembly/disassembly.h"
#include <time.h>
struct CommandHelpItem {
@ -81,9 +82,17 @@ LR"(.ps [show processes list]
LR"(.pstree [show process tree]
.pstree 1234/0x3200 [show process tree parent id = 1234 or 0x3200])" },
{ L".mm", "CmdMemoryInfo", LR"(show memory information)",
{ L".mm", "CmdMemoryEditor", LR"(memory editor)",
LR"(.mm [show os memory]
.mm -pid 1234 [show process pid=1234 memory information])" },
.mm i 1234 [show process pid=1234 memory information]
.mm r 1234 40000 100 [read process(pid=1234) memory, 0x40000:0x100]
.mm w 1234 40000 cccc9090 [write process(pid=1234) memory, 0x40000=>0xcc 0xcc 0x90 0x90)" },
{ L".fs", "CmdFileEditor", LR"(file editor)",
LR"(.fs [show os memory]
.fs i c:\my.txt [show my.txt information]
.fs r c:\my.txt 0 100/all [read my.txt, 0:0x100/all]
.fs w c:\my.txt 0 cccc9090 [write my.txt, 0x0=>0xcc 0xcc 0x90 0x90)" },
};
Cmds::Cmds(QTextBrowser *parent) :
@ -151,12 +160,14 @@ Q_INVOKABLE void Cmds::CmdCls(QStringList argv)
Q_INVOKABLE void Cmds::CmdCmd(QStringList argv)
{
std::wstring line;
if (argv.size() == 1)
line = VariantFilePath(line);
for (size_t i = 0; i < argv.size(); i++) {
line.append(argv[i].toStdWString());
if (i != (argv.size()-1))
line.append(L" ");
}
auto cmd = L"cmd.exe /c " + line;
auto &&cmd = L"cmd.exe /c " + line;
std::string out;
DWORD code;
ReadConsoleOutput(UNONE::StrToA(cmd), out, code);
@ -170,6 +181,8 @@ Q_INVOKABLE void Cmds::CmdCmd(QStringList argv)
Q_INVOKABLE void Cmds::CmdStart(QStringList argv)
{
std::wstring line;
if (argv.size() == 1)
line = VariantFilePath(line);
for (size_t i = 0; i < argv.size(); i++) {
line.append(argv[i].toStdWString());
if (i != (argv.size() - 1))
@ -609,7 +622,7 @@ Q_INVOKABLE void Cmds::CmdProcessTree(QStringList argv)
CmdException(ECMD_PARAM_INVALID);
}
Q_INVOKABLE void Cmds::CmdMemoryInfo(QStringList argv)
Q_INVOKABLE void Cmds::CmdMemoryEditor(QStringList argv)
{
SIZE_T PageSize;
auto OutMemoryInfoStyle1 = [&](wchar_t* name, SIZE_T size) {
@ -644,7 +657,7 @@ Q_INVOKABLE void Cmds::CmdMemoryInfo(QStringList argv)
return;
}
if (argc == 2) {
if (argv[0] == "-pid") {
if (argv[0] == "i") {
DWORD pid = VariantInt(argv[1].toStdString(), 10);
PROCESS_MEMORY_COUNTERS_EX mm_info;
if (!UNONE::MmGetProcessMemoryInfo(pid, mm_info))
@ -665,10 +678,89 @@ Q_INVOKABLE void Cmds::CmdMemoryInfo(QStringList argv)
return;
}
}
if (argc == 4) {
DWORD pid = VariantInt(argv[1].toStdString(), 10);
if (argv[0] == "r") {
HANDLE phd = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
ON_SCOPE_EXIT([&phd] {if (phd) CloseHandle(phd); });
if (!phd) return ERR(L"OpenProcess pid:%d err:%d", pid, GetLastError());
DWORD64 addr = VariantInt64(argv[2].toStdString());
DWORD size = VariantInt(argv[3].toStdString());
std::string buf;
buf.resize(size);
SIZE_T readlen;
bool ret = ReadProcessMemory(phd, (LPCVOID)addr, (LPVOID)buf.data(), size, &readlen);
if (!ret && size != readlen) {
return ERR(L"ReadProcessMemory pid:%d err:%d, expect:%d readlen:%d", pid, GetLastError(), size, readlen);
}
auto &&hexdump = HexDumpMemory(addr, (char*)buf.data(), buf.size());
UNONE::StrReplaceA(hexdump, "<", "&lt;");
return CmdOutput("%s", hexdump.c_str());
}
if (argv[0] == "w") {
HANDLE phd = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_WRITE, FALSE, pid);
ON_SCOPE_EXIT([&phd] {if (phd) CloseHandle(phd); });
if (!phd) return ERR(L"OpenProcess pid:%d err:%d", pid, GetLastError());
DWORD64 addr = VariantInt64(argv[2].toStdString());
auto &&buf = argv[3].toStdString();
UNONE::StrReplaceA(buf, ".");
buf = UNONE::StrHexStrToStreamA(buf);
SIZE_T writelen;
bool ret = WriteProcessMemory(phd, (LPVOID)addr, (LPVOID)buf.data(), buf.size(), &writelen);
if (!ret && buf.size() != writelen) {
return ERR(L"WriteProcessMemory pid:%d err:%d, expect:%d readlen:%d", pid, GetLastError(), buf.size(), writelen);
}
return CmdOutput("WriteProcessMemory addr:%llx size:%d ok", addr, writelen);
}
}
CmdException(ECMD_PARAM_INVALID);
}
Q_INVOKABLE void Cmds::CmdFileEditor(QStringList argv)
{
auto argc = argv.size();
if (argc == 2) {
if (argv[0] == "i") {
DWORD64 size;
auto &&path = argv[1].toStdWString();
UNONE::FsGetFileSizeW(path, size);
CmdOutput(L"FilePath: %s", path.c_str());
CmdOutput(L"FileSize: %lld", size);
return;
}
}
if (argc == 4 || argc == 2) {
if (argv[0] == "r") {
auto &&path = argv[1].toStdWString();
std::string buf;
DWORD64 offset = 0;
if (argc == 2) {
UNONE::FsReadFileDataW(path, buf);
} else {
offset = VariantInt64(argv[2].toStdString());
DWORD64 size = VariantInt(argv[3].toStdString());
ReadFileDataW(path, offset, size, buf);
}
auto &&hexdump = HexDumpMemory(offset, (char*)buf.data(), buf.size());
UNONE::StrReplaceA(hexdump, "<", "&lt;");
return CmdOutput("%s", hexdump.c_str());
}
if (argv[0] == "w") {
auto &&path = argv[1].toStdWString();
auto &&buf = argv[3].toStdString();
DWORD64 offset = VariantInt64(argv[2].toStdString());
UNONE::StrReplaceA(buf, ".");
buf = UNONE::StrHexStrToStreamA(buf);
if (WriteFileDataW(path, offset, buf)) {
CmdOutput("WriteFile offset:%llx size:%d ok", offset, buf.size());
}
return;
}
}
CmdException(ECMD_PARAM_INVALID);
}
QString Cmds::CmdGetLast()
{
QString cmdline;

3
src/OpenArk/cmds/cmds.h

@ -45,7 +45,8 @@ public:
Q_INVOKABLE void CmdWndInfo(QStringList argv);
Q_INVOKABLE void CmdProcessInfo(QStringList argv);
Q_INVOKABLE void CmdProcessTree(QStringList argv);
Q_INVOKABLE void CmdMemoryInfo(QStringList argv);
Q_INVOKABLE void CmdMemoryEditor(QStringList argv);
Q_INVOKABLE void CmdFileEditor(QStringList argv);
QString CmdGetLast();
QString CmdGetNext();

7
src/OpenArk/common/app/app.cpp

@ -21,7 +21,7 @@ QApplication *app = nullptr;
QTranslator *app_tr = nullptr;
OpenArk *openark = nullptr;
bool LogOutput(LogOuputLevel lev, const char* func, const wchar_t* format, ...)
void LogOutput(LogOuputLevel lev, const char* func, const wchar_t* format, ...)
{
QString levelstr;
struct { int lev; QString levstr; } levels[] = {
@ -48,16 +48,13 @@ bool LogOutput(LogOuputLevel lev, const char* func, const wchar_t* format, ...)
va_end(lst);
openark->onLogOutput(QString::fromStdWString(str));
return true;
}
bool LogOutput(LogOuputLevel lev, const char* func, const char* format, ...)
void LogOutput(LogOuputLevel lev, const char* func, const char* format, ...)
{
va_list lst;
va_start(lst, format);
std::wstring&& wstr = UNONE::StrToW(UNONE::StrFormatVaListA(format, lst));
LogOutput(lev, func, L"%s", wstr.c_str());
va_end(lst);
return true;
}

4
src/OpenArk/common/app/app.h

@ -22,8 +22,8 @@ extern QTranslator *app_tr;
extern OpenArk *openark;
enum LogOuputLevel { LevelInfo, LevelWarn, LevelErr, LevelDbg };
bool LogOutput(LogOuputLevel lev, const char* func, const char* format, ...);
bool LogOutput(LogOuputLevel lev, const char* func, const wchar_t* format, ...);
void LogOutput(LogOuputLevel lev, const char* func, const char* format, ...);
void LogOutput(LogOuputLevel lev, const char* func, const wchar_t* format, ...);
#define INFO(format, ...) \
LogOutput(LevelInfo, __FUNCTION__, (format), __VA_ARGS__)
#define WARN(format, ...) \

6
src/OpenArk/common/cpp-wrapper/cpp-wrapper.cpp

@ -75,4 +75,10 @@ int64_t VariantInt64(std::string val, int radix)
case 16: return UNONE::StrToHex64A(val);
default: return UNONE::StrToHex64A(val);
}
}
std::wstring VariantFilePath(std::wstring path)
{
UNONE::StrReplaceIW(path, L"file:///");
return std::move(path);
}

3
src/OpenArk/common/cpp-wrapper/cpp-wrapper.h

@ -50,4 +50,5 @@ private: // noncopyable
#define ON_SCOPE_EXIT(callback) ScopeGuard SCOPEGUARD_LINENAME(EXIT, __LINE__)(callback)
int VariantInt(std::string val, int radix = 16);
int64_t VariantInt64(std::string val, int radix = 16);
int64_t VariantInt64(std::string val, int radix = 16);
std::wstring VariantFilePath(std::wstring path);

89
src/OpenArk/common/win-wrapper/win-wrapper.cpp

@ -371,4 +371,91 @@ bool ExtractResource(const QString &res, const QString &path)
return false;
}
return true;
}
}
bool WriteFileDataW(__in const std::wstring& fpath, __in int64_t offset, __in const std::string& fdata)
{
bool result = false;
bool read_only = false;
DWORD saved_attr = GetFileAttributesW(fpath.c_str());
if (saved_attr != INVALID_FILE_ATTRIBUTES) {
if (saved_attr & FILE_ATTRIBUTE_READONLY) {
read_only = true;
SetFileAttributesW(fpath.c_str(), saved_attr&(~FILE_ATTRIBUTE_READONLY));
}
}
HANDLE fd = CreateFileW(fpath.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (fd != INVALID_HANDLE_VALUE) {
DWORD writelen;
LARGE_INTEGER li;
li.QuadPart = offset;
SetFilePointer(fd, li.LowPart, &li.HighPart, FILE_BEGIN);
if (WriteFile(fd, fdata.data(), (DWORD)fdata.size(), &writelen, NULL)) {
if (fdata.size() == writelen) {
result = true;
} else {
ERR(L"WriteFile %s err, expected-size:%d actual-size:%d", fpath.c_str(), fdata.size(), writelen);
}
} else {
ERR(L"WriteFile %s err:%d", fpath.c_str(), GetLastError());
}
CloseHandle(fd);
} else {
ERR(L"CreateFileW %s err:%d", fpath.c_str(), GetLastError());
}
if (read_only)
SetFileAttributesW(fpath.c_str(), saved_attr);
return result;
}
bool ReadFileDataW(__in const std::wstring &fpath, __in int64_t offset, __in int64_t readsize, __out std::string &fdata)
{
bool result = false;
DWORD fsize = 0;
HANDLE fd = CreateFileW(fpath.c_str(), GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (fd == INVALID_HANDLE_VALUE) {
ERR(L"CreateFileW %s err:%d", fpath.c_str(), GetLastError());
return false;
}
fsize = GetFileSize(fd, NULL);
if (fsize == INVALID_FILE_SIZE) {
ERR(L"GetFileSize %s err:%d", fpath.c_str(), GetLastError());
CloseHandle(fd);
return false;
}
if ((offset+readsize) > fsize) {
WARN(L"read offset out of bound");
readsize = fsize - offset;
}
LARGE_INTEGER li;
li.QuadPart = offset;
SetFilePointer(fd, li.LowPart, &li.HighPart, FILE_BEGIN);
char* buff = new(std::nothrow) char[readsize];
if (buff == NULL) {
ERR(L"alloc memory err");
CloseHandle(fd);
return false;
}
DWORD readlen;
if (ReadFile(fd, buff, readsize, &readlen, NULL)) {
if (readlen == readsize) {
try {
fdata.assign(buff, readsize);
result = true;
} catch (std::exception& e) {
fdata.clear();
ERR("c++ exception: %s", e.what());
} catch (...) {
fdata.clear();
ERR("c++ exception: unknown");
}
} else {
ERR(L"ReadFile %s err, expected-size:%d actual-size:%d", fpath.c_str(), readsize, readlen);
}
} else {
ERR(L"ReadFile %s err:%d", fpath.c_str(), GetLastError());
}
delete[] buff;
CloseHandle(fd);
return result;
}

2
src/OpenArk/common/win-wrapper/win-wrapper.h

@ -35,3 +35,5 @@ void WinShowProperties(const std::wstring &path);
bool GetCertOwner(const QString &path, QString &owner);
bool ObGetObjectName(HANDLE hd, std::string& obj_name);
bool ExtractResource(const QString &res, const QString &path);
bool WriteFileDataW(__in const std::wstring& fpath, __in int64_t offset, __in const std::string& fdata);
bool ReadFileDataW(__in const std::wstring &fpath, __in int64_t offset, __in int64_t readsize, __out std::string &fdata);

3
src/OpenArkDrv/OpenArkDrv.vcxproj

@ -244,6 +244,9 @@
<ItemGroup>
<ResourceCompile Include="OpenArkDrv.rc" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>

3
src/OpenArkDrv/OpenArkDrv.vcxproj.filters

@ -69,4 +69,7 @@
<Filter>res</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
</Project>
Loading…
Cancel
Save