mirror of
https://github.com/sirjonasxx/G-Earth.git
synced 2024-11-26 18:30:52 +01:00
Merge pull request #8 from XePeleato/windowsDev
Add cache support for Windows & general refactoring
This commit is contained in:
commit
7724dbea14
Binary file not shown.
@ -98,7 +98,7 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
@ -148,11 +148,15 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ctpl_stl.h" />
|
||||
<ClInclude Include="Process.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
<ClInclude Include="thread_pool.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="G-WinMem.cpp" />
|
||||
<ClCompile Include="Process.cpp" />
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
@ -161,6 +165,5 @@
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="ExtensionTargets" />
|
||||
</Project>
|
@ -21,6 +21,15 @@
|
||||
<ClInclude Include="targetver.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Process.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ctpl_stl.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="thread_pool.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
@ -29,5 +38,8 @@
|
||||
<ClCompile Include="G-WinMem.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Process.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
263
G-WinMem/G-WinMem/Process.cpp
Normal file
263
G-WinMem/G-WinMem/Process.cpp
Normal file
@ -0,0 +1,263 @@
|
||||
|
||||
#include "ctpl_stl.h"
|
||||
#include "Process.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
|
||||
Process::Process() : Process(0)
|
||||
{}
|
||||
|
||||
Process::Process(int pid)
|
||||
: mPid(pid),
|
||||
mHandle(nullptr)
|
||||
{}
|
||||
|
||||
bool Process::Open()
|
||||
{
|
||||
mHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_OPERATION, false, mPid);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<MemoryChunk*> Process::GetChunks()
|
||||
{
|
||||
return mChunks;
|
||||
}
|
||||
|
||||
void Process::Close()
|
||||
{
|
||||
CloseHandle(mHandle);
|
||||
}
|
||||
|
||||
void Process::PrintCachedResults(std::vector<u_char *> cache)
|
||||
{
|
||||
const auto offset = 4;
|
||||
static std::mutex m;
|
||||
Open();
|
||||
|
||||
for (auto addr : cache) {
|
||||
u_char rawMem[1024] = { 0 };
|
||||
|
||||
if (!ReadProcessMemory(mHandle, addr, rawMem, 1024, nullptr))
|
||||
{
|
||||
std::cout << "Failed to read memory at " << addr << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto i = 0; i < (1024 - ((256 - 1) * offset)); i += offset)
|
||||
{
|
||||
unsigned char wannabeRC4data[1024] = { 0 };
|
||||
unsigned char data[256] = { 0 };
|
||||
memcpy(wannabeRC4data, rawMem + i, 1024);
|
||||
|
||||
auto isvalid = true;
|
||||
|
||||
for (auto j = 0; j < 1024; j++)
|
||||
{
|
||||
if (j % 4 != 0 && wannabeRC4data[j] != 0)
|
||||
{
|
||||
isvalid = false;
|
||||
break;
|
||||
}
|
||||
if (j % 4 == 0)
|
||||
{
|
||||
data[j / 4] = wannabeRC4data[j];
|
||||
}
|
||||
}
|
||||
if (isvalid)
|
||||
{
|
||||
m.lock();
|
||||
for (auto idx : data)
|
||||
printf("%02X", static_cast<signed char>(idx) & 0xFF);
|
||||
|
||||
std::cout << std::endl;
|
||||
m.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
Close();
|
||||
}
|
||||
|
||||
void Process::PrintRC4Possibilities()
|
||||
{
|
||||
SYSTEM_INFO sys_info;
|
||||
|
||||
static std::mutex m;
|
||||
|
||||
GetSystemInfo(&sys_info);
|
||||
|
||||
Open();
|
||||
|
||||
FindMaps(sys_info);
|
||||
|
||||
const auto offset = 4;
|
||||
|
||||
CreateMapsForRC4();
|
||||
|
||||
for (auto k = 0; k < mRC4Maps.size(); k++)
|
||||
{
|
||||
auto mem = mRC4Maps[k];
|
||||
|
||||
if (mem->mSize >= 1024 && mem->mSize <= 1024 + 2 * offset)
|
||||
{
|
||||
for (auto i = 0; i < (mem->mSize - ((256 - 1) * offset)); i += offset)
|
||||
{
|
||||
unsigned char wannabeRC4data[1024] = { 0 };
|
||||
unsigned char data[256] = { 0 };
|
||||
memcpy(wannabeRC4data, static_cast<unsigned char *>(mem->mStart) + i, 1024);
|
||||
|
||||
auto isvalid = true;
|
||||
|
||||
for (auto j = 0; j < 1024; j++)
|
||||
{
|
||||
if (j % 4 != 0 && wannabeRC4data[j] != 0)
|
||||
{
|
||||
isvalid = false;
|
||||
break;
|
||||
}
|
||||
if (j % 4 == 0)
|
||||
{
|
||||
data[j / 4] = wannabeRC4data[j];
|
||||
}
|
||||
}
|
||||
if (isvalid)
|
||||
{
|
||||
m.lock();
|
||||
printf("%llx\n",reinterpret_cast<unsigned long long>(mOutCache[k]));
|
||||
for (auto idx : data)
|
||||
printf("%02X", static_cast<signed char>(idx) & 0xFF);
|
||||
|
||||
std::cout << std::endl;
|
||||
m.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
delete mem;
|
||||
}
|
||||
Close();
|
||||
}
|
||||
|
||||
void Process::CreateMapFromChunk(MemoryChunk *chunk)
|
||||
{
|
||||
const auto offset = 4;
|
||||
const auto dump = new unsigned char[chunk->mSize + 1];
|
||||
|
||||
memset(dump, 0, chunk->mSize + 1);
|
||||
|
||||
if (!ReadProcessMemory(mHandle, chunk->mStart, dump, chunk->mSize, nullptr))
|
||||
{
|
||||
std::cout << "Failed to read memory at: " << chunk->mStart << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
auto maskCount = 0;
|
||||
int nToMap[256] = { 0 };
|
||||
int removeMap[256] = { 0 };
|
||||
|
||||
for (auto i = 0; i < 256; i++) {
|
||||
nToMap[i] = -1;
|
||||
removeMap[i] = -1;
|
||||
}
|
||||
|
||||
auto matchStart = -1;
|
||||
auto matchEnd = -1;
|
||||
|
||||
for (auto i = 0; i < chunk->mSize; i += offset)
|
||||
{
|
||||
const auto b = (static_cast<int>(dump[i]) + 128) % 256;
|
||||
const auto indInMap = (i / 4) % 256;
|
||||
|
||||
const auto deletedNumber = removeMap[indInMap];
|
||||
|
||||
if (deletedNumber != -1)
|
||||
{
|
||||
nToMap[deletedNumber] = -1;
|
||||
maskCount--;
|
||||
removeMap[indInMap] = -1;
|
||||
}
|
||||
|
||||
if (nToMap[b] == -1)
|
||||
{
|
||||
maskCount++;
|
||||
removeMap[indInMap] = b;
|
||||
nToMap[b] = indInMap;
|
||||
}
|
||||
else
|
||||
{
|
||||
removeMap[nToMap[b]] = -1;
|
||||
removeMap[indInMap] = b;
|
||||
nToMap[b] = indInMap;
|
||||
}
|
||||
|
||||
if (maskCount == 256)
|
||||
{
|
||||
if (matchStart == -1)
|
||||
{
|
||||
matchStart = i - ((256 - 1) * offset);
|
||||
matchEnd = i;
|
||||
}
|
||||
|
||||
if (matchEnd < i - ((256 - 1) * offset))
|
||||
{
|
||||
//printf("maybeValid -> %p\n", static_cast<u_char*>(chunk->mStart) + matchStart);
|
||||
mOutCache.push_back(static_cast<u_char *>(chunk->mStart) + matchStart);
|
||||
mRC4Maps.push_back(new MemoryChunk(dump + matchStart, matchEnd - matchStart + 4));
|
||||
|
||||
matchStart = i - ((256 - 1) * offset);
|
||||
}
|
||||
matchEnd = i;
|
||||
}
|
||||
}
|
||||
if (matchStart != -1)
|
||||
{
|
||||
mOutCache.push_back(static_cast<u_char*>(chunk->mStart) + matchStart);
|
||||
mRC4Maps.push_back(new MemoryChunk(dump + matchStart, matchEnd - matchStart + 4));
|
||||
}
|
||||
delete chunk;
|
||||
}
|
||||
|
||||
void Process::CreateMapsForRC4()
|
||||
{
|
||||
ctpl::thread_pool p(5);
|
||||
|
||||
for (auto chunk : mChunks) {
|
||||
p.push(std::bind(&Process::CreateMapFromChunk, this, chunk));
|
||||
}
|
||||
|
||||
p.stop(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Process::FindMaps(SYSTEM_INFO sys_info)
|
||||
{
|
||||
|
||||
auto addr = reinterpret_cast<uintptr_t>(sys_info.lpMinimumApplicationAddress);
|
||||
const auto end = reinterpret_cast<uintptr_t>(sys_info.lpMaximumApplicationAddress);
|
||||
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
|
||||
while (addr < end) {
|
||||
if (!VirtualQueryEx(mHandle, reinterpret_cast<LPCVOID>(addr), &mbi, sizeof(mbi))) {
|
||||
std::cout << "Failed to get memory maps\n";
|
||||
return;
|
||||
}
|
||||
|
||||
if (mbi.State == MEM_COMMIT && ((mbi.Protect & PAGE_GUARD) == 0) && ((mbi.Protect & PAGE_NOACCESS) == 0)) {
|
||||
mChunks.push_back(new MemoryChunk(reinterpret_cast<LPVOID>(addr), mbi.RegionSize));
|
||||
}
|
||||
addr += mbi.RegionSize;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Process::~Process()
|
||||
{
|
||||
for (auto m : mChunks)
|
||||
delete m;
|
||||
|
||||
for (auto m : mRC4Maps)
|
||||
delete m;
|
||||
}
|
40
G-WinMem/G-WinMem/Process.h
Normal file
40
G-WinMem/G-WinMem/Process.h
Normal file
@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
#include <Windows.h>
|
||||
#include <vector>
|
||||
|
||||
class MemoryChunk
|
||||
{
|
||||
public:
|
||||
MemoryChunk(LPVOID start, SIZE_T size);
|
||||
LPVOID mStart;
|
||||
SIZE_T mSize;
|
||||
};
|
||||
|
||||
inline MemoryChunk::MemoryChunk(LPVOID start, SIZE_T size) :
|
||||
mStart(start),
|
||||
mSize(size)
|
||||
{}
|
||||
|
||||
|
||||
class Process
|
||||
{
|
||||
public:
|
||||
Process();
|
||||
Process(int pid);
|
||||
bool Open();
|
||||
void Close();
|
||||
void FindMaps(SYSTEM_INFO sys_info);
|
||||
void CreateMapsForRC4();
|
||||
void CreateMapFromChunk(MemoryChunk *chunk);
|
||||
void PrintRC4Possibilities();
|
||||
void PrintCachedResults(std::vector<u_char *> cache);
|
||||
~Process();
|
||||
std::vector<MemoryChunk*> GetChunks();
|
||||
private:
|
||||
int mPid;
|
||||
HANDLE mHandle;
|
||||
std::vector<MemoryChunk*> mChunks;
|
||||
std::vector<MemoryChunk*> mRC4Maps;
|
||||
std::vector<LPVOID> mOutCache;
|
||||
};
|
||||
|
256
G-WinMem/G-WinMem/ctpl_stl.h
Normal file
256
G-WinMem/G-WinMem/ctpl_stl.h
Normal file
@ -0,0 +1,256 @@
|
||||
/*********************************************************
|
||||
*
|
||||
* Copyright (C) 2014 by Vitaliy Vitsentiy
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*********************************************************/
|
||||
|
||||
|
||||
#ifndef __ctpl_stl_thread_pool_H__
|
||||
#define __ctpl_stl_thread_pool_H__
|
||||
|
||||
#include <functional>
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <exception>
|
||||
#include <future>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
|
||||
|
||||
|
||||
// thread pool to run user's functors with signature
|
||||
// ret func(int id, other_params)
|
||||
// where id is the index of the thread that runs the functor
|
||||
// ret is some return type
|
||||
|
||||
|
||||
namespace ctpl {
|
||||
|
||||
namespace detail {
|
||||
template <typename T>
|
||||
class Queue {
|
||||
public:
|
||||
bool push(T const & value) {
|
||||
std::unique_lock<std::mutex> lock(this->mutex);
|
||||
this->q.push(value);
|
||||
return true;
|
||||
}
|
||||
// deletes the retrieved element, do not use for non integral types
|
||||
bool pop(T & v) {
|
||||
std::unique_lock<std::mutex> lock(this->mutex);
|
||||
if (this->q.empty())
|
||||
return false;
|
||||
v = this->q.front();
|
||||
this->q.pop();
|
||||
return true;
|
||||
}
|
||||
bool empty() {
|
||||
std::unique_lock<std::mutex> lock(this->mutex);
|
||||
return this->q.empty();
|
||||
}
|
||||
private:
|
||||
std::queue<T> q;
|
||||
std::mutex mutex;
|
||||
};
|
||||
}
|
||||
|
||||
class thread_pool {
|
||||
|
||||
public:
|
||||
|
||||
thread_pool() { this->init(); }
|
||||
thread_pool(int nThreads) { this->init(); this->resize(nThreads); }
|
||||
|
||||
// the destructor waits for all the functions in the queue to be finished
|
||||
~thread_pool() {
|
||||
this->stop(true);
|
||||
}
|
||||
|
||||
// get the number of running threads in the pool
|
||||
int size() { return static_cast<int>(this->threads.size()); }
|
||||
|
||||
// number of idle threads
|
||||
int n_idle() { return this->nWaiting; }
|
||||
int n_pending() { return this->nPending; }
|
||||
std::thread & get_thread(int i) { return *this->threads[i]; }
|
||||
|
||||
// change the number of threads in the pool
|
||||
// should be called from one thread, otherwise be careful to not interleave, also with this->stop()
|
||||
// nThreads must be >= 0
|
||||
void resize(int nThreads) {
|
||||
if (!this->isStop && !this->isDone) {
|
||||
int oldNThreads = static_cast<int>(this->threads.size());
|
||||
if (oldNThreads <= nThreads) { // if the number of threads is increased
|
||||
this->threads.resize(nThreads);
|
||||
this->flags.resize(nThreads);
|
||||
|
||||
for (int i = oldNThreads; i < nThreads; ++i) {
|
||||
this->flags[i] = std::make_shared<std::atomic<bool>>(false);
|
||||
this->set_thread(i);
|
||||
}
|
||||
}
|
||||
else { // the number of threads is decreased
|
||||
for (int i = oldNThreads - 1; i >= nThreads; --i) {
|
||||
*this->flags[i] = true; // this thread will finish
|
||||
this->threads[i]->detach();
|
||||
}
|
||||
{
|
||||
// stop the detached threads that were waiting
|
||||
std::unique_lock<std::mutex> lock(this->mutex);
|
||||
this->cv.notify_all();
|
||||
}
|
||||
this->threads.resize(nThreads); // safe to delete because the threads are detached
|
||||
this->flags.resize(nThreads); // safe to delete because the threads have copies of shared_ptr of the flags, not originals
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// empty the queue
|
||||
void clear_queue() {
|
||||
std::function<void(int id)> * _f;
|
||||
while (this->q.pop(_f))
|
||||
delete _f; // empty the queue
|
||||
}
|
||||
|
||||
// pops a functional wrapper to the original function
|
||||
std::function<void(int)> pop() {
|
||||
std::function<void(int id)> * _f = nullptr;
|
||||
this->q.pop(_f);
|
||||
std::unique_ptr<std::function<void(int id)>> func(_f); // at return, delete the function even if an exception occurred
|
||||
std::function<void(int)> f;
|
||||
if (_f)
|
||||
f = *_f;
|
||||
return f;
|
||||
}
|
||||
|
||||
// wait for all computing threads to finish and stop all threads
|
||||
// may be called asynchronously to not pause the calling thread while waiting
|
||||
// if isWait == true, all the functions in the queue are run, otherwise the queue is cleared without running the functions
|
||||
void stop(bool isWait = false) {
|
||||
if (!isWait) {
|
||||
if (this->isStop)
|
||||
return;
|
||||
this->isStop = true;
|
||||
for (int i = 0, n = this->size(); i < n; ++i) {
|
||||
*this->flags[i] = true; // command the threads to stop
|
||||
}
|
||||
this->clear_queue(); // empty the queue
|
||||
}
|
||||
else {
|
||||
if (this->isDone || this->isStop)
|
||||
return;
|
||||
this->isDone = true; // give the waiting threads a command to finish
|
||||
}
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(this->mutex);
|
||||
this->cv.notify_all(); // stop all waiting threads
|
||||
}
|
||||
for (int i = 0; i < static_cast<int>(this->threads.size()); ++i) { // wait for the computing threads to finish
|
||||
if (this->threads[i]->joinable())
|
||||
this->threads[i]->join();
|
||||
}
|
||||
// if there were no threads in the pool but some functors in the queue, the functors are not deleted by the threads
|
||||
// therefore delete them here
|
||||
this->clear_queue();
|
||||
this->threads.clear();
|
||||
this->flags.clear();
|
||||
}
|
||||
|
||||
template<typename F, typename... Rest>
|
||||
auto push(F && f, Rest&&... rest) ->std::future<decltype(f(0, rest...))> {
|
||||
auto pck = std::make_shared<std::packaged_task<decltype(f(0, rest...))(int)>>(
|
||||
std::bind(std::forward<F>(f), std::placeholders::_1, std::forward<Rest>(rest)...)
|
||||
);
|
||||
auto _f = new std::function<void(int id)>([pck](int id) {
|
||||
(*pck)(id);
|
||||
});
|
||||
++this->nPending;
|
||||
this->q.push(_f);
|
||||
std::unique_lock<std::mutex> lock(this->mutex);
|
||||
this->cv.notify_one();
|
||||
return pck->get_future();
|
||||
}
|
||||
|
||||
// run the user's function that excepts argument int - id of the running thread. returned value is templatized
|
||||
// operator returns std::future, where the user can get the result and rethrow the catched exceptins
|
||||
template<typename F>
|
||||
auto push(F && f) ->std::future<decltype(f(0))> {
|
||||
auto pck = std::make_shared<std::packaged_task<decltype(f(0))(int)>>(std::forward<F>(f));
|
||||
auto _f = new std::function<void(int id)>([pck](int id) {
|
||||
(*pck)(id);
|
||||
});
|
||||
++this->nPending;
|
||||
this->q.push(_f);
|
||||
std::unique_lock<std::mutex> lock(this->mutex);
|
||||
this->cv.notify_one();
|
||||
return pck->get_future();
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// deleted
|
||||
thread_pool(const thread_pool &);// = delete;
|
||||
thread_pool(thread_pool &&);// = delete;
|
||||
thread_pool & operator=(const thread_pool &);// = delete;
|
||||
thread_pool & operator=(thread_pool &&);// = delete;
|
||||
|
||||
void set_thread(int i) {
|
||||
std::shared_ptr<std::atomic<bool>> flag(this->flags[i]); // a copy of the shared ptr to the flag
|
||||
auto f = [this, i, flag/* a copy of the shared ptr to the flag */]() {
|
||||
std::atomic<bool> & _flag = *flag;
|
||||
std::function<void(int id)> * _f;
|
||||
bool isPop = this->q.pop(_f);
|
||||
while (true) {
|
||||
while (isPop) { // if there is anything in the queue
|
||||
--this->nPending;
|
||||
std::unique_ptr<std::function<void(int id)>> func(_f); // at return, delete the function even if an exception occurred
|
||||
(*_f)(i);
|
||||
if (_flag)
|
||||
return; // the thread is wanted to stop, return even if the queue is not empty yet
|
||||
else
|
||||
isPop = this->q.pop(_f);
|
||||
}
|
||||
// the queue is empty here, wait for the next command
|
||||
std::unique_lock<std::mutex> lock(this->mutex);
|
||||
++this->nWaiting;
|
||||
this->cv.wait(lock, [this, &_f, &isPop, &_flag]() { isPop = this->q.pop(_f); return isPop || this->isDone || _flag; });
|
||||
--this->nWaiting;
|
||||
if (!isPop)
|
||||
return; // if the queue is empty and this->isDone == true or *flag then return
|
||||
}
|
||||
};
|
||||
this->threads[i].reset(new std::thread(f)); // compiler may not support std::make_unique()
|
||||
}
|
||||
|
||||
void init() { this->nWaiting = 0; this->nPending = 0; this->isStop = false; this->isDone = false; }
|
||||
|
||||
std::vector<std::unique_ptr<std::thread>> threads;
|
||||
std::vector<std::shared_ptr<std::atomic<bool>>> flags;
|
||||
detail::Queue<std::function<void(int id)> *> q;
|
||||
std::atomic<bool> isDone;
|
||||
std::atomic<bool> isStop;
|
||||
std::atomic<int> nWaiting; // how many threads are waiting
|
||||
std::atomic<int> nPending; // how many tasks are waiting
|
||||
|
||||
std::mutex mutex;
|
||||
std::condition_variable cv;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __ctpl_stl_thread_pool_H__
|
@ -1,5 +1,6 @@
|
||||
package main.protocol.memory.habboclient.windows;
|
||||
|
||||
import main.misc.Cacher;
|
||||
import main.protocol.HConnection;
|
||||
import main.protocol.HMessage;
|
||||
import main.protocol.TrafficListener;
|
||||
@ -32,22 +33,61 @@ public class WindowsHabboClient extends HabboClient {
|
||||
|
||||
@Override
|
||||
public List<byte[]> getRC4cached() {
|
||||
List<byte[]> result = new ArrayList<>();
|
||||
try {
|
||||
List<String> possibleResults = readPossibleBytes(true);
|
||||
|
||||
if (possibleResults == null)
|
||||
return new ArrayList<>();
|
||||
|
||||
for (String s : possibleResults)
|
||||
result.add(hexStringToByteArray(s));
|
||||
} catch (IOException | URISyntaxException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private ArrayList<String> readPossibleBytes() throws IOException, URISyntaxException {
|
||||
ProcessBuilder pb = new ProcessBuilder(new File(this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI()).getParent() + "\\G-WinMem.exe", hConnection.getClientHostAndPort().substring(0, hConnection.getClientHostAndPort().indexOf(':')) , Integer.toString(hConnection.getPort()));
|
||||
private ArrayList<String> readPossibleBytes(boolean useCache) throws IOException, URISyntaxException {
|
||||
ProcessBuilder pb = null;
|
||||
List<String> cachedOffsets = (List<String>) Cacher.get("RC4Offsets");
|
||||
StringJoiner joiner = new StringJoiner(" ");
|
||||
|
||||
if (useCache) {
|
||||
if (cachedOffsets == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (String s : cachedOffsets) {
|
||||
joiner.add(s);
|
||||
}
|
||||
}
|
||||
|
||||
if (!useCache)
|
||||
pb = new ProcessBuilder(new File(this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI()).getParent() + "\\G-WinMem.exe", hConnection.getClientHostAndPort().substring(0, hConnection.getClientHostAndPort().indexOf(':')) , Integer.toString(hConnection.getPort()));
|
||||
else
|
||||
pb = new ProcessBuilder(new File(this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI()).getParent() + "\\G-WinMem.exe", hConnection.getClientHostAndPort().substring(0, hConnection.getClientHostAndPort().indexOf(':')) , Integer.toString(hConnection.getPort()), "-c" + joiner.toString());
|
||||
|
||||
|
||||
Process p = pb.start();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||
|
||||
String line;
|
||||
ArrayList<String> possibleData = new ArrayList<>();
|
||||
|
||||
cachedOffsets = new ArrayList<>();
|
||||
|
||||
int count = 0;
|
||||
while((line = reader.readLine()) != null) {
|
||||
if (line.length() > 1) {
|
||||
if (!useCache && (count++ % 2 == 0)) {
|
||||
cachedOffsets.add(line);
|
||||
}
|
||||
else
|
||||
possibleData.add(line);
|
||||
}
|
||||
}
|
||||
Cacher.put("RC4Offsets", cachedOffsets);
|
||||
p.destroy();
|
||||
return possibleData;
|
||||
}
|
||||
@ -56,7 +96,7 @@ public class WindowsHabboClient extends HabboClient {
|
||||
public List<byte[]> getRC4possibilities() {
|
||||
List<byte[]> result = new ArrayList<>();
|
||||
try {
|
||||
ArrayList<String> possibleData = readPossibleBytes();
|
||||
ArrayList<String> possibleData = readPossibleBytes(false);
|
||||
|
||||
for (String possibleHexStr : possibleData) {
|
||||
result.add(hexStringToByteArray(possibleHexStr));
|
||||
|
Loading…
Reference in New Issue
Block a user