[DLL] [SRC] ASI Loader v 1.2 by Silent - Форум Cheat-Master.ru
  • Страница 1 из 1
  • 1
Модератор форума: Sanoxxx, Alowir  
[DLL] [SRC] ASI Loader v 1.2 by Silent
Сержик Дата: Воскресенье, 26.06.2016, 15:31 | Сообщение # 1
Новичок
Сообщений: 2
Статус: Offline
ASI Loader v 1.2 by Silent

Чтобы долго не искать его, в ознакомительном виде решил выложить сюда.
Может быть, кому-то будет нужен.

vorbisFile.dll (vorbisFile.cpp)

Код

// GTA: SA ASI Loader 1.2
// Written by Silent
// Based on ASI Loader by Stanislav "listener" Golovin
// Initialization part made by NTAuthority

#include <windows.h>
#include <iostream>

BYTE      originalCode[5];
BYTE*      originalEP = 0;
HINSTANCE    hExecutableInstance;

//=============================================================================
// vorbisfile connector
extern "C" {
struct ov_callbacks {
size_t (*read_func) (void* ptr, size_t size, size_t nmemb, void* datasource);
int (*seek_func) (void* datasource, long long offset, int whence);
int (*close_func) (void* datasource);
long (*tell_func) (void* datasource);
};

void* __ov_open_callbacks;
__declspec(dllexport, naked) int ov_open_callbacks(void* datasource, void* vf, char* initial, long ibytes, ov_callbacks callbacks)
{ _asm jmp __ov_open_callbacks }

void* __ov_clear;
__declspec(dllexport, naked) int ov_clear(void* vf)
{ _asm jmp __ov_clear }

void* __ov_time_total;
__declspec(dllexport, naked) double ov_time_total (void* vf, int i)
{ _asm jmp __ov_time_total }

void* __ov_time_tell;
__declspec(dllexport, naked) double ov_time_tell(void* vf)
{ _asm jmp __ov_time_tell }

void* __ov_read;
__declspec(dllexport, naked) long ov_read(void* vf, char* buffer, int length, int bigendianp, int word, int sgned, int* bitstream)
{ _asm jmp __ov_read }

void* __ov_info;
__declspec(dllexport, naked) void* ov_info(void* vf, int link)
{ _asm jmp __ov_info }

void* __ov_time_seek;
__declspec(dllexport, naked) int ov_time_seek(void* vf, double pos)
{ _asm jmp __ov_time_seek }

void* __ov_time_seek_page;
__declspec(dllexport, naked) int ov_time_seek_page(void* vf, double pos)
{ _asm jmp __ov_time_seek_page }

}

struct ExcludedEntry {
char*   entry;
ExcludedEntry*    prev;
ExcludedEntry*    next;
};

struct ExcludedEntriesList {
ExcludedEntry*    first;
ExcludedEntry*    last;
};

void ExcludedEntriesListInit(ExcludedEntriesList* list)
{
list->first = NULL;
list->last = NULL;
}

void ExcludedEntriesListPush(ExcludedEntriesList* list, const char* entryName)
{
ExcludedEntry*  newEntry = (ExcludedEntry*)malloc(sizeof(ExcludedEntry));
int    length = strlen(entryName) + 1;
if ( !list->first )
list->first = newEntry;
else
list->last->next = newEntry;

newEntry->prev = list->last;
newEntry->next = NULL;
list->last = newEntry;

newEntry->entry = (char*)malloc(length);
strncpy(newEntry->entry, entryName, length);
}

bool ExcludedEntriesListHasEntry(ExcludedEntriesList* list, const char* entryName)
{
ExcludedEntry*    it = list->first;
while ( it )
{
if ( !_stricmp(it->entry, entryName) )
{
// It has an entry, we can pop it now
if ( it->next )
it->next->prev = it->prev;
if ( it->prev )
it->prev->next = it->next;

if ( list->first == it )
list->first = it->next;

free(it->entry);
free(it);
return true;
}
it = it->next;
}

return false;
}

void ExcludedEntriesListFree(ExcludedEntriesList* list)
{
ExcludedEntry*    it = list->first;
while ( it )
{
ExcludedEntry* nextEntry = it->next;
free(it->entry);
free(it);
it = nextEntry;
}
}

void FindFiles(WIN32_FIND_DATA* fd, ExcludedEntriesList* list)
{
HANDLE asiFile = FindFirstFile ("*.asi", fd);
if (asiFile != INVALID_HANDLE_VALUE)
{

do {
if (!(fd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {

unsigned int pos = 5;
while (fd->cFileName[pos])
++pos;
if (fd->cFileName[pos-4] == '.' &&
(fd->cFileName[pos-3] == 'a' || fd->cFileName[pos-3] == 'A') &&
(fd->cFileName[pos-2] == 's' || fd->cFileName[pos-2] == 'S') &&
(fd->cFileName[pos-1] == 'i' || fd->cFileName[pos-1] == 'I'))
{
if ( !list || !ExcludedEntriesListHasEntry(list, fd->cFileName) )
LoadLibrary (fd->cFileName);
}
}

} while (FindNextFile (asiFile, fd));
FindClose (asiFile);
}
}

void LoadPlugins()
{
HMODULE vorbisHooked = LoadLibrary ("vorbishooked");
if ( vorbisHooked )
{
__ov_open_callbacks = GetProcAddress (vorbisHooked, "ov_open_callbacks");
__ov_clear = GetProcAddress (vorbisHooked, "ov_clear");
__ov_time_total = GetProcAddress (vorbisHooked, "ov_time_total");
__ov_time_tell = GetProcAddress (vorbisHooked, "ov_time_tell");
__ov_read = GetProcAddress (vorbisHooked, "ov_read");
__ov_info = GetProcAddress (vorbisHooked, "ov_info");
__ov_time_seek = GetProcAddress (vorbisHooked, "ov_time_seek");
__ov_time_seek_page = GetProcAddress (vorbisHooked, "ov_time_seek_page");

// Regular ASI Loader
WIN32_FIND_DATA fd;
char   moduleName[MAX_PATH];
char   preparedPath[128];    // stores scripts\*exename*\settings.ini
char*   tempPointer;
int    nWantsToLoadPlugins;
int    nThatExeWantsPlugins;

GetModuleFileName(NULL, moduleName, MAX_PATH);
tempPointer = strrchr(moduleName, '.');
*tempPointer = '\0';

tempPointer = strrchr(moduleName, '\\');
strncpy(preparedPath, "scripts", 8);
strcat(preparedPath, tempPointer);
strcat(preparedPath, "\\settings.ini");

// Before we load any ASI files, let's see if user wants to do it at all
nWantsToLoadPlugins = GetPrivateProfileInt("globalsets", "loadplugins", TRUE, "scripts\\global.ini");
// Or perhaps this EXE wants to override global settings?
nThatExeWantsPlugins = GetPrivateProfileInt("exclusivesets", "loadplugins", -1, preparedPath);

if ( nThatExeWantsPlugins )    // Will not process only if this EXE wishes not to load anything but its exclusive plugins
{
if ( nWantsToLoadPlugins || nThatExeWantsPlugins == TRUE )
{
// Load excludes
ExcludedEntriesList    excludes;

ExcludedEntriesListInit(&excludes);
if ( FILE* iniFile = fopen(preparedPath, "rt") )
{
char    line[256];
bool    bItsExcludesList = false;

while ( fgets(line, 256, iniFile) )
{
char*    newline = strchr(line, '\n');

if ( newline )
*newline = '\0';

if ( bItsExcludesList )
{
if ( line[0] && line[0] != ';' )
ExcludedEntriesListPush(&excludes, line);
}
else
{
if ( !_stricmp(line, "[excludes]") )
bItsExcludesList = true;
}
}

fclose(iniFile);
}
FindFiles(&fd, &excludes);
if ( SetCurrentDirectory("scripts\\") )
{
FindFiles(&fd, &excludes);
if ( SetCurrentDirectory(tempPointer + 1) )
{
FindFiles(&fd, NULL);    // Exclusive plugins are not being excluded
SetCurrentDirectory("..\\..\\");
}
else
SetCurrentDirectory("..\\");
}

// Free the remaining excludes
ExcludedEntriesListFree(&excludes);
}
}
else
{
// Load only exclusive plugins, if exists
// We need to cut settings.ini from the path again
tempPointer = strrchr(preparedPath, '\\');
tempPointer[1] = '\0';
if ( SetCurrentDirectory(preparedPath) )
{
FindFiles(&fd, NULL);
SetCurrentDirectory("..\\..\\");
}
}
}

// Unprotect the module NOW (CLEO 4.1.1.30f crash fix)
IMAGE_NT_HEADERS* ntHeader = (IMAGE_NT_HEADERS*)((DWORD)hExecutableInstance + ((IMAGE_DOS_HEADER*)hExecutableInstance)->e_lfanew);

SIZE_T size = ntHeader->OptionalHeader.SizeOfImage;
DWORD oldProtect;
VirtualProtect((VOID*)hExecutableInstance, size, PAGE_EXECUTE_READWRITE, &oldProtect);
}

static bool   bLoadedPluginsYet = false;

void WINAPI CustomGetStartupInfoA(LPSTARTUPINFOA lpStartupInfo)
{
if ( !bLoadedPluginsYet )
{
// At the time this is called, the EXE is fully decrypted - we don't need any tricks from the ASI side
LoadPlugins();
bLoadedPluginsYet = true;
}
GetStartupInfoA(lpStartupInfo);
}

void WINAPI CustomGetStartupInfoW(LPSTARTUPINFOW lpStartupInfo)
{
if ( !bLoadedPluginsYet )
{
// At the time this is called, the EXE is fully decrypted - we don't need any tricks from the ASI side
LoadPlugins();
bLoadedPluginsYet = true;
}
GetStartupInfoW(lpStartupInfo);
}

void PatchIAT()
{
// Find IAT
IMAGE_NT_HEADERS*   ntHeader = (IMAGE_NT_HEADERS*)((DWORD)hExecutableInstance + ((IMAGE_DOS_HEADER*)hExecutableInstance)->e_lfanew);
IMAGE_IMPORT_DESCRIPTOR*    pImports = (IMAGE_IMPORT_DESCRIPTOR*)((DWORD)hExecutableInstance + ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
DWORD      nNumImports = ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size / sizeof(IMAGE_IMPORT_DESCRIPTOR) - 1;

// Find kernel32.dll
for ( DWORD i = 0; i < nNumImports; i++ )
{
if ( !_stricmp((const char*)((DWORD)hExecutableInstance + pImports->Name), "KERNEL32.DLL") )
{
IMAGE_IMPORT_BY_NAME**  pFunctions = (IMAGE_IMPORT_BY_NAME**)((DWORD)hExecutableInstance + pImports->OriginalFirstThunk);

// kernel32.dll found, find GetStartupInfoA
for ( DWORD j = 0; pFunctions[j]; j++ )
{
if ( !_stricmp((const char*)((DWORD)hExecutableInstance + pFunctions[j]->Name), "GetStartupInfoA") )
{
// Overwrite the address with the address to a custom GetStartupInfoA
DWORD  dwProtect[2];
DWORD*  pAddress = &((DWORD*)((DWORD)hExecutableInstance + pImports->FirstThunk))[j];

VirtualProtect(pAddress, sizeof(DWORD), PAGE_EXECUTE_READWRITE, &dwProtect[0]);
*pAddress = (DWORD)CustomGetStartupInfoA;
VirtualProtect(pAddress, sizeof(DWORD), dwProtect[0], &dwProtect[1]);

// return to the original EP
*(DWORD*)originalEP = *(DWORD*)&originalCode;
*(BYTE*)(originalEP+4) = originalCode[4];
return;
}

// For new SA Steam EXE
if ( !_stricmp((const char*)((DWORD)hExecutableInstance + pFunctions[j]->Name), "GetStartupInfoW") )
{
// Overwrite the address with the address to a custom GetStartupInfoA
DWORD  dwProtect[2];
DWORD*  pAddress = &((DWORD*)((DWORD)hExecutableInstance + pImports->FirstThunk))[j];

VirtualProtect(pAddress, sizeof(DWORD), PAGE_EXECUTE_READWRITE, &dwProtect[0]);
*pAddress = (DWORD)CustomGetStartupInfoW;
VirtualProtect(pAddress, sizeof(DWORD), dwProtect[0], &dwProtect[1]);

// return to the original EP
*(DWORD*)originalEP = *(DWORD*)&originalCode;
*(BYTE*)(originalEP+4) = originalCode[4];
return;
}
}
}
pImports++;
}

// No luck. Oh well.
// return to the original EP anyway
*(DWORD*)originalEP = *(DWORD*)&originalCode;
*(BYTE*)(originalEP+4) = originalCode[4];
}

void __declspec(naked) Main_DoInit()
{
_asm
{
call    PatchIAT
jmp  originalEP
}
}

BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
if ( ul_reason_for_call == DLL_PROCESS_ATTACH )
{
hExecutableInstance = GetModuleHandle(NULL); // passing NULL should be safe even with the loader lock being held (according to ReactOS ldr.c)

if (hExecutableInstance)
{
IMAGE_NT_HEADERS* ntHeader = (IMAGE_NT_HEADERS*)((DWORD)hExecutableInstance + ((IMAGE_DOS_HEADER*)hExecutableInstance)->e_lfanew);
BYTE* ep = (BYTE*)((DWORD)hExecutableInstance + ntHeader->OptionalHeader.AddressOfEntryPoint);

// Unprotect the entry point
DWORD oldProtect;
VirtualProtect(ep, 5, PAGE_EXECUTE_READWRITE, &oldProtect);

// back up original code
*(DWORD*)&originalCode = *(DWORD*)ep;
originalCode[4] = *(ep+4);

// patch to call our EP
int newEP = (int)Main_DoInit - ((int)ep + 5);
ep[0] = 0xE9;

*(int*)&ep[1] = newEP;

originalEP = ep;
}
}
return TRUE;
}


compile.bat


Код

cl -c /GS- /GF /O2 vorbisFile.cpp
link /dll /nodefaultlib /entry:_DllMainCRTStartup@12 vorbisFile.obj Kernel32.lib LIBCMT.LIB


Сообщение отредактировал Сержик - Понедельник, 27.06.2016, 10:06
  • Страница 1 из 1
  • 1
Поиск:
Статистика Форума
Лучшие пользователи
Admin [39113]

GеNius [7210]

[CM]Russel [5557]

kenlo763 [4952]

[CM]AGRESSOR [4639]

Snake_Firm [4452]

Сэс [4416]

Artem_Buero [4223]

[CM]Durman [3204]

[CM]Рафаэль [3080]

iMaddy [2855]

sky_Woker [2854]

getrekt [2745]

Новые пользователи
nonaxn11 [23:52]

arbuzikkks [17:38]

gwendolyngd2 [16:08]

Drywallwje [11:38]

TronAccs [05:11]

danilka05cher [03:05]

kennethhf2 [00:44]

nikitaw13w [15:10]

samp-sampovec [15:05]

eddieqk11 [12:49]

pennytl16 [12:18]

hermaneo16 [07:35]

lunaries [07:13]