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 8 years ago
parent
commit
b084ff353a
  1. BIN
      Ashita.dll
  2. BIN
      injector.exe
  3. 148
      plugins/ADK/AS_Memory.h

BIN
Ashita.dll

Binary file not shown.

BIN
injector.exe

Binary file not shown.

148
plugins/ADK/AS_Memory.h

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

Loading…
Cancel
Save