Browse Source

Reverted memory scanner changes, the newer method was too unreliable.

Reverted change includes some minor updates, using a less overhead object than a vector.
pull/45/head
atom0s 7 years ago
parent
commit
b084ff353a
  1. BIN
      Ashita.dll
  2. BIN
      injector.exe
  3. 154
      plugins/ADK/AS_Memory.h

BIN
Ashita.dll

Binary file not shown.

BIN
injector.exe

Binary file not shown.

154
plugins/ADK/AS_Memory.h

@ -36,73 +36,27 @@ @@ -36,73 +36,27 @@
namespace Ashita
{
class Memory
/**
* Iteratable object to reduce the overhead of using a vector.
*/
template<typename T>
struct scannableiterator_t
{
public:
/**
* Determines the length of data from the given offset valid to scan with.
*
* @param {std::vector} pattern - The pattern to find the length within.
* @param {uintptr_t} offset - The offset to begin iterating at.
* @returns {uintptr_t} The length of data from the given offset.
*/
static uintptr_t FindLength(const std::vector<std::pair<uint8_t, bool>>& pattern, uintptr_t offset)
{
// Ensure the offset is within the pattern range..
if (offset >= pattern.size())
return 0;
auto len = 0;
for (size_t x = 0; x < pattern.size(); x++)
{
// Compare the data for wildcards or null characters..
if (pattern[x].second == false ||
pattern[x].first == 0x00)
break;
len++;
}
return len;
}
/**
* Finds the largest chunk of valid data within the pattern to scan for.
*
* @param {std::vector} pattern - The pattern to find the chunk within.
* @param {int32_t [2]} output - The output data to store the offset and length of data to use.
*/
static void FindLargestChunk(const std::vector<std::pair<uint8_t, bool>>& pattern, uintptr_t output[2])
{
auto offset = (uintptr_t)0;
auto length = (uintptr_t)FindLength(pattern, 0);
auto maxlen = (uintptr_t)pattern.size();
// Loop the pattern and find its largest chunk..
for (auto x = length; x < maxlen; x++)
{
// Ensure the data is required..
if (pattern[x].second != true)
continue;
uintptr_t m_BaseAddress;
uintptr_t m_BaseSize;
// Find the length at the given offset..
auto count = FindLength(pattern, x);
if (count > length)
{
offset = x;
length = count;
}
// Step past the current data..
if (count > 0)
x += count - 1;
}
scannableiterator_t(uintptr_t base, uintptr_t size)
: m_BaseAddress(base), m_BaseSize(size)
{ }
scannableiterator_t(const scannableiterator_t&) = delete;
// Return the largest offset and length..
output[0] = offset;
output[1] = length;
}
T* begin(void) { return (T*)this->m_BaseAddress; }
T* end(void) { return (T*)(this->m_BaseAddress + this->m_BaseSize); }
};
class Memory
{
public:
/**
* Finds a pattern within the given range of data.
*
@ -136,69 +90,35 @@ namespace Ashita @@ -136,69 +90,35 @@ namespace Ashita
}
}
// Find the largest chunk of valid data to scan with..
uintptr_t p[2] = { 0 };
FindLargestChunk(vpattern, p);
// Prepare the required variables..
const auto psize = vpattern.size();
const auto pstart = p[0];
const auto plen = (intptr_t)p[1];
const auto pfirst = vpattern[0].first;
// Build the wildcard table..
uint8_t wildcard[UCHAR_MAX + 1] = { 0 };
for (auto x = pstart; x < pstart + plen; x++)
wildcard[(uint8_t)vpattern[x].first] = 1;
// Create a scanner object to use with the STL functions..
scannableiterator_t<uint8_t> data(baseAddress, baseSize);
auto scanStart = data.begin();
auto result = (uintptr_t)0;
const auto data = (uint8_t*)baseAddress;
const auto size = (uint32_t)baseSize;
std::vector<uintptr_t> matches;
// Loop the data and look for the pattern..
for (intptr_t x = size - psize; x >= 0; x--)
while (true)
{
auto c = data[x];
auto w = wildcard[c];
auto k = 0;
// Step over wildcard characters..
while (w == 0 && x > (intptr_t)plen)
// Search for the pattern..
auto ret = std::search(scanStart, data.end(), vpattern.begin(), vpattern.end(),
[&](uint8_t curr, std::pair<uint8_t, bool> currPattern)
{
x -= plen;
w = wildcard[data[x]];
k = 1;
}
return (!currPattern.second) || curr == currPattern.first;
});
if (k == 1)
// Did we find a match..
if (ret != data.end())
{
x++;
continue;
}
// If we hit the usage count, return the result..
if (result == count || count == 0)
return (std::distance(data.begin(), ret) + baseAddress) + offset;
// Ensure the first byte matches..
if (c != pfirst) continue;
// Validate the size..
if (x - pstart < 0 || x - pstart + psize > size)
return 0;
// Walk the pattern and match its data..
for (size_t y = 0; y < psize; y++)
{
if (y == pstart || vpattern[y].second != true)
continue;
if (data[x - pstart + y] != vpattern[y].first)
break;
if (y + 1 == psize)
matches.insert(matches.begin(), (uintptr_t)(data + (x - pstart)) + offset);
// Increment the found count and scan again..
++result;
scanStart = ++ret;
}
else
break;
}
// Handle the count match..
if (count < matches.size())
return matches[count];
return 0;
}

Loading…
Cancel
Save