aboutsummaryrefslogtreecommitdiff
path: root/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_minesweeper.cpp
blob: 0d61227fa28aca1abc7244acb6f72d7996618ad9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*	Benjamin DELPY `gentilkiwi`
	http://blog.gentilkiwi.com
	benjamin@gentilkiwi.com
	Licence : http://creativecommons.org/licenses/by/3.0/fr/
*/
#include "mod_mimikatz_minesweeper.h"
#include "..\global.h"

char DISP_MINESWEEPER[] = "012345678.F? !!";

vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_minesweeper::getMimiKatzCommands()
{
	vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector;
	monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(infos,	L"infos",	L"Obtient des informations sur le démineur en cours"));
	return monVector;
}

bool mod_mimikatz_minesweeper::infos(vector<wstring> * arguments)
{
	structHandleAndAddr * maStruct = new structHandleAndAddr();
	if(giveHandleAndAddr(maStruct))
	{
		STRUCT_MINESWEEPER_GAME monGame;
		if(mod_memory::readMemory(maStruct->G, &monGame, sizeof(STRUCT_MINESWEEPER_GAME), maStruct->hMineSweeper))
		{
#ifdef _M_IX86
			if(mod_system::GLOB_Version.dwBuildNumber >= 7000)
				monGame.pBoard = monGame.pBoard_WIN7x86;
#endif
			STRUCT_MINESWEEPER_BOARD monBoard;
			if(mod_memory::readMemory(monGame.pBoard, &monBoard, sizeof(STRUCT_MINESWEEPER_BOARD), maStruct->hMineSweeper))
			{
				(*outputStream) << L"Mines           : " << monBoard.nbMines << endl <<
					L"Dimension       : " << monBoard.nbLignes << L" lignes x " << monBoard.nbColonnes << L" colonnes" << endl <<
					L"Champ           : " << endl << endl;

				char ** monTableau;
				monTableau = new char*[monBoard.nbLignes];
				for(DWORD l = 0; l < monBoard.nbLignes; l++)
					monTableau[l] = new char[monBoard.nbColonnes];
					
				parseField(maStruct, monBoard.ref_visibles, monTableau, true);
				parseField(maStruct, monBoard.ref_mines, monTableau, false);

				for(DWORD l = 0; l < monBoard.nbLignes; l++)
				{
					(*outputStream) << L'\t';
					for(DWORD c = 0; c < monBoard.nbColonnes; c++)
						(*outputStream) << monTableau[l][c] << L' ';
					(*outputStream) << endl;
					delete[] monTableau[l];
				}
				delete[] monTableau;
			} else (*outputStream) << L"Impossible de lire les données du plateau" << endl;
		} else (*outputStream) << L"Impossible de lire les données du jeu" << endl;
		CloseHandle(maStruct->hMineSweeper);
	}
	delete maStruct;

	return true;
}

bool mod_mimikatz_minesweeper::parseField(structHandleAndAddr * monHandleAndAddr, PSTRUCT_MINESWEEPER_REF_ELEMENT laBase, char ** monTableau, bool isVisible)
{
	DWORD tailleElementFinal = isVisible ? sizeof(DWORD) : sizeof(BYTE);
	
	STRUCT_MINESWEEPER_REF_ELEMENT maRefElements;
	if(mod_memory::readMemory(laBase, &maRefElements, sizeof(STRUCT_MINESWEEPER_REF_ELEMENT), monHandleAndAddr->hMineSweeper))
	{
		PSTRUCT_MINESWEEPER_REF_ELEMENT * ref_colonnes_elements = new PSTRUCT_MINESWEEPER_REF_ELEMENT[maRefElements.nbElements];
		if(mod_memory::readMemory(maRefElements.elements, ref_colonnes_elements, maRefElements.nbElements * sizeof(PSTRUCT_MINESWEEPER_REF_ELEMENT), monHandleAndAddr->hMineSweeper))
		{
			for(DWORD c = 0; c < maRefElements.nbElements; c++)
			{
				STRUCT_MINESWEEPER_REF_ELEMENT maRefColonneElement;	
				if(mod_memory::readMemory(ref_colonnes_elements[c], &maRefColonneElement, sizeof(STRUCT_MINESWEEPER_REF_ELEMENT), monHandleAndAddr->hMineSweeper))
				{		
					void * cellules = isVisible ? reinterpret_cast<void *>(new DWORD[maRefColonneElement.nbElements]) : reinterpret_cast<void *>(new BYTE[maRefColonneElement.nbElements]);
					if(mod_memory::readMemory(maRefColonneElement.elements, cellules, maRefColonneElement.nbElements * tailleElementFinal, monHandleAndAddr->hMineSweeper))
					{	
						for(DWORD l = 0; l < maRefColonneElement.nbElements; l++)
						{
							if(isVisible)
								monTableau[l][c] = DISP_MINESWEEPER[reinterpret_cast<DWORD *>(cellules)[l]];
							else
								if(reinterpret_cast<BYTE *>(cellules)[l]) monTableau[l][c] = '*';
						}
					} else (*outputStream) << L"Impossible de lire les élements de la colonne : "  << c << endl;
					delete[] cellules;
				} else (*outputStream) << L"Impossible de lire les références de la colonne : "  << c << endl;
			}
		} else (*outputStream) << L"Impossible de lire les références des colonnes" << endl;
		delete[] ref_colonnes_elements;
	} else (*outputStream) << L"Impossible de lire les références de l\'élement" << endl;

	return true;
}

bool mod_mimikatz_minesweeper::giveHandleAndAddr(structHandleAndAddr * monHandleAndAddr)
{
#ifdef _M_X64
	BYTE PTRN_WIN6_Game_SafeGetSingleton[] = {0x48, 0x89, 0x44, 0x24, 0x70, 0x48, 0x85, 0xc0, 0x74, 0x0a, 0x48, 0x8b, 0xc8, 0xe8};
	LONG OFFS_WIN6_ToG	= -(5 + 5 + 6 + 4 + 1);
#elif defined _M_IX86
	BYTE PTRN_WIN6_Game_SafeGetSingleton[] = {0x84, 0xc0, 0x75, 0x07, 0x6a, 0x67, 0xe8};
	LONG OFFS_WIN6_ToG	= sizeof(PTRN_WIN6_Game_SafeGetSingleton) + 4 + 1;
#endif
	RtlZeroMemory(monHandleAndAddr, sizeof(structHandleAndAddr));

	wstring nomDemineur(L"minesweeper.exe");
	mod_process::KIWI_PROCESSENTRY32 monDemineur;
	if(mod_process::getUniqueForName(&monDemineur, &nomDemineur))
	{
		monHandleAndAddr->pidMineSweeper = monDemineur.th32ProcessID;
		mod_process::KIWI_MODULEENTRY32 monModule;
		if(mod_process::getUniqueModuleForName(&monModule, NULL, &monDemineur.th32ProcessID))
		{
			PBYTE limit = monModule.modBaseAddr + monModule.modBaseSize, ptrTemp = NULL;
			if(monHandleAndAddr->hMineSweeper = OpenProcess(PROCESS_VM_READ, false, monHandleAndAddr->pidMineSweeper))
				if(mod_memory::searchMemory(monModule.modBaseAddr, limit, PTRN_WIN6_Game_SafeGetSingleton, &ptrTemp, sizeof(PTRN_WIN6_Game_SafeGetSingleton), true, monHandleAndAddr->hMineSweeper))
				{
#ifdef _M_X64
					long offsetTemp = 0;
					if(mod_memory::readMemory(ptrTemp + OFFS_WIN6_ToG, &offsetTemp, sizeof(offsetTemp), monHandleAndAddr->hMineSweeper))
						mod_memory::readMemory((ptrTemp + OFFS_WIN6_ToG) + sizeof(long) + offsetTemp + 1, &monHandleAndAddr->G, sizeof(monHandleAndAddr->G), monHandleAndAddr->hMineSweeper);
#elif defined _M_IX86
					if(mod_memory::readMemory(ptrTemp + OFFS_WIN6_ToG, &ptrTemp, sizeof(ptrTemp), monHandleAndAddr->hMineSweeper))
						mod_memory::readMemory(ptrTemp, &monHandleAndAddr->G, sizeof(monHandleAndAddr->G), monHandleAndAddr->hMineSweeper);
#endif
				}
		}
	}

	bool reussite = monHandleAndAddr->hMineSweeper && monHandleAndAddr->G;

	if(!reussite && monHandleAndAddr->hMineSweeper)
		CloseHandle(monHandleAndAddr->hMineSweeper);

	return reussite;
}