I can hook any other function, but not ExitProcess.
Here is the code to demonstrate this:
#include <iostream>
#include <cstdlib>
#include <Windows.h>
#include <Psapi.h>
void __stdcall NewSleep(DWORD milliseconds)
{
std::cout << "Sleep." << std::endl;
std::cin.get();
}
void __stdcall NewExitProcess(UINT exitCode)
{
std::cout << "ExitProcess." << std::endl;
std::cin.get();
}
FARPROC f1 = NULL;
FARPROC f2 = NULL;
int main()
{
HMODULE kernel32Module = GetModuleHandle("KERNEL32.dll");
f1 = GetProcAddress(kernel32Module, "Sleep");
f2 = GetProcAddress(kernel32Module, "ExitProcess");
std::cout << f1 << std::endl;
unsigned char* baseAddress = (unsigned char*)GetModuleHandle(NULL);
IMAGE_DOS_HEADER* idh = (IMAGE_DOS_HEADER*)baseAddress;
IMAGE_NT_HEADERS* inh = (IMAGE_NT_HEADERS*)(baseAddress + idh->e_lfanew);
IMAGE_IMPORT_DESCRIPTOR* iid = (IMAGE_IMPORT_DESCRIPTOR*)(baseAddress + inh->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
for (IMAGE_IMPORT_DESCRIPTOR* i = iid; i->Name != 0; ++i)
{
std::string moduleName = (char*)(baseAddress + i->Name);
if (moduleName == "KERNEL32.dll")
{
IMAGE_THUNK_DATA* itd = (IMAGE_THUNK_DATA*)(baseAddress + i->FirstThunk);
for (IMAGE_THUNK_DATA* j = itd; j->u1.Function != 0; ++j)
{
if ((FARPROC)j->u1.Function == f1)
{
DWORD oldProtect = 0;
VirtualProtect(&j->u1.Function, sizeof(DWORD), PAGE_READWRITE, &oldProtect);
j->u1.Function = (DWORD)&NewSleep;
VirtualProtect(&j->u1.Function, sizeof(DWORD), oldProtect, &oldProtect);
}
if ((FARPROC)j->u1.Function == f2)
{
DWORD oldProtect = 0;
VirtualProtect(&j->u1.Function, sizeof(DWORD), PAGE_READWRITE, &oldProtect);
j->u1.Function = (DWORD)&NewExitProcess;
VirtualProtect(&j->u1.Function, sizeof(DWORD), oldProtect, &oldProtect);
}
}
break;
}
}
Sleep(0);
Sleep(0);
ExitProcess(0);
//Crash.
std::cin.sync();
std::cin.get();
return EXIT_SUCCESS;
}
It calls the hooked function, but when NewExitProcess returns I get an access violation. The calls to Sleep are fine, just like any hooked function other than ExitProcess.
EDIT: I get the same issue when hooking ExitThread though.
When looking up the function declaration of ExitProcess you will find something like this:
WINBASEAPI
DECLSPEC_NORETURN
VOID
WINAPI
ExitProcess(
_In_ UINT uExitCode
);
The interesting part is DECLSPEC_NORETURN which is defined as __declspec(noreturn). It's also an attribute used by the ExitThread function that was also causing a crash for you. Looking up on the docs, we find this:
This __declspec attribute tells the compiler that a function does not return. As a consequence, the compiler knows that the code following a call to a __declspec(noreturn) function is unreachable.
According to your findings, it is not only used to disable compiler warnings, but is also used for optimization. This also explains why it would work in Debug mode.
I can't think of a good solution for this, as you are fighting the optimizer. The solution you wrote in a comment did not work for me (VS2013, Release mode, /O2). I came up with something a bit silly, but it seems to do the job for me:
int *ptr = (int*)&ExitProcess;
ptr++;
ptr--;
((VOID (WINAPI*)(UINT))ptr)(0);
In general, hooking ExitProcess of another unknown program should always exit the current thread, because it may be compiled to not have any code to return to.
Related
I have written a function which It is doing the Fibonacci calculation. I wanted to start and execute it with CreateThread as a thread. Finally, I want to save the result of the thread (the Fibonacci) and show it in the console. What is the problem with my code? It doesn't work properly. It starts the thread, but I don't know how should I store the result of the thread and show it.
#include <Windows.h>
#include <iostream>
DWORD WINAPI Fibonacci(LPVOID arg_repeat) {
DWORD dwValue = *(int*)arg_repeat;
if (dwValue < 3)
return 1;
return Fibonacci((int*)dwValue - 1) + Fibonacci((int*)dwValue - 2);
}
auto main(int argc, const char* argv[]) -> decltype(0) {
DWORD dwFibonacciValue;
std::cout << "Fibonacci Value: ";
std::cin >> dwFibonacciValue;
DWORD dwThreadId;
HANDLE hThreading = CreateThread(NULL, 0, Fibonacci, &dwFibonacciValue, NULL, &dwThreadId);
WaitForSingleObject(hThreading, INFINITE);
std::cout << "Fibonacci Result: " << dwResult << std::endl;
CloseHandle(hThreading);
return 0;
}
Your code is wrong beause (int*)dwValue - 1 is not a valid pointer.
You should separate the thread function from the fibonacci function. There will be much less dubious and wrong casts and code will be much clearer:
#include <Windows.h>
#include <iostream>
// Clean and easy to read fibonacci function without fancy casts
DWORD Fibonacci(DWORD dwValue) {
if (dwValue < 3)
return 1;
return Fibonacci(dwValue - 1) + Fibonacci(dwValue - 2);
}
// Thread function
DWORD WINAPI Thread(LPVOID arg_repeat) {
return Fibonacci(*(DWORD*)arg_repeat); // the only cast int the whole code
}
int main(int argc, const char* argv[]) -> decltype(0) {
// it's 'int main', not 'auto main'
DWORD dwFibonacciValue;
std::cout << "Fibonacci Value: ";
std::cin >> dwFibonacciValue;
DWORD dwThreadId;
HANDLE hThreading = CreateThread(NULL, 0, Thread, &dwFibonacciValue, 0, &dwThreadId);
WaitForSingleObject(hThreading, INFINITE);
// get return value of the thread (your actual question)
DWORD dwResult;
GetExitCodeThread(hThreading, &dwResult);
std::cout << "Fibonacci Result: " << dwResult << std::endl;
CloseHandle(hThreading);
return 0;
}
There is no error check whatsoever in this code for clarity.
Other detail:
CreateThread(NULL, 0, Thread, &dwFibonacciValue, NULL, &dwThreadId);
// ^ you should provide a DWORD
// here and not a pointer
should be
CreateThread(NULL, 0, Thread, &dwFibonacciValue, 0, &dwThreadId);
I want to allocate some memory inside a specific module of a process instead of the process in general. The following Windows C++ code can allocate memory inside a process given its process id:
#include "pch.h"
#include <windows.h>
#include <winternl.h>
#include <processthreadsapi.h>
#include <iostream>
#include <conio.h>
#pragma comment(lib, "ntdll.lib")
typedef NTSTATUS (NTAPI *nt_alloc_virtual_memory_func)(HANDLE process_handle, PVOID* base_address, ULONG_PTR zero_bits,
PSIZE_T region_size, ULONG allocation_type, ULONG protect);
typedef NTSTATUS (NTAPI *nt_free_virtual_memory_func)(HANDLE process_handle, PVOID* base_address, PSIZE_T region_size,
ULONG free_type);
void enable_allocating_executable_memory()
{
PROCESS_MITIGATION_DYNAMIC_CODE_POLICY mp;
ZeroMemory(&mp, sizeof mp);
mp.ProhibitDynamicCode = FALSE;
SetProcessMitigationPolicy(ProcessDynamicCodePolicy, &mp, sizeof mp);
}
long allocate_memory(char** arguments, const HANDLE process_handle, PVOID process_memory, SIZE_T& allocation_size)
{
const auto memory_size = arguments[3];
allocation_size = strtoul(memory_size, nullptr, 10);
const auto nt_allocate_virtual_memory = reinterpret_cast<nt_alloc_virtual_memory_func>(GetProcAddress(
GetModuleHandle(L"ntdll.dll"), "NtAllocateVirtualMemory"));
const auto allocation_status = nt_allocate_virtual_memory(process_handle, &process_memory, 0, &allocation_size,
MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (NT_SUCCESS(allocation_status))
{
std::cout << std::hex << process_memory << std::endl;
}
return allocation_status;
}
int free_memory(const int argument_count, char** arguments,
const HANDLE process_handle, SIZE_T& mem_size)
{
const auto address_string = arguments[3];
const auto process_address = strtoull(address_string, nullptr, 16);
auto process_memory_address = reinterpret_cast<PVOID>(process_address);
if (argument_count < 4)
{
return EXIT_FAILURE;
}
const auto memory_size = arguments[4];
mem_size = strtoul(memory_size, nullptr, 10);
const auto nt_free_virtual_memory = reinterpret_cast<nt_free_virtual_memory_func>(GetProcAddress(
GetModuleHandle(L"ntdll.dll"), "NtFreeVirtualMemory"));
const auto status = nt_free_virtual_memory(process_handle, &process_memory_address, &mem_size, MEM_RELEASE);
return status;
}
int main(const int argument_count, char* arguments[])
{
if (argument_count < 4)
{
return EXIT_FAILURE;
}
const auto process_id_string = arguments[1];
const auto process_id = strtoul(process_id_string, nullptr, 10);
enable_allocating_executable_memory();
const auto process_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process_id);
if (process_handle == nullptr)
{
std::cout << "Cannot open process with process id " << process_id << std::endl;
exit(EXIT_FAILURE);
}
const PVOID process_memory = nullptr;
SIZE_T mem_size;
const auto command = arguments[2];
if (strcmp(command, "--allocate") == 0)
{
allocate_memory(arguments, process_handle, process_memory, mem_size);
}
else if (strcmp(command, "--free") == 0)
{
return free_memory(argument_count, arguments, process_handle, mem_size);
}
return EXIT_SUCCESS;
}
NtAllocateVirtualMemory does not seem to accept an argument for a module. What else can be used?
The reasoning behind this is that I don't want to have jmps going from one module to another after I allocated some memory but rather stay as locally as possible. This also makes jmp instructions shorter in terms of their sizes in memory.
I want to allocate some memory inside a specific module
You cannot do this, when a module is mapped it's memory is allocated. You can't allocate memory inside the module, the module exists inside it's allocated pages and no where else. Any allocated pages will be outside of the module.
Alternatively if you want to use memory which is already allocated but is not used, this called a code cave. It's typically an area of memory inside a module which is filled with zeros. So you can scan for a code cave by finding a certain length of redundant zeros inside the module and then you can write to that memory.
This is done frequently and is especially useful if the page has the execute bit set as you won't have to change any permissions which could be deemed risky.
This is also done frequently in injectors which use "scatter mapping" where it only uses these code caves to inject code.
I am trying to make a program to store the value 500 into the calculator's memory address for the MR (Memory Restore) button on the calculator application.
I know that the address for this integer is
"calc.exe"+00073320 + 0 + C
If I use a program like cheat engine, I can get the current address for the instance of the calculator.exe i'm running, and write to it just fine that way. However, since this is not a static address, I need a way to get the module base address.
I tried using this GetModuleBase function (see code below) to get the Base Address of the calc.exe, but my issue is that I cannot get the base address. The function always returns 0 instead of the correct address.
I debugged it and found that in the GetModuleBase function, it is not even cycling once through the while loop because bModule is returning 0 from the Module32First function.
#include <tchar.h>
#include <windows.h>
#include <TlHelp32.h>
#include <iostream>
#include <Psapi.h>
#include <wchar.h>
#pragma comment( lib, "psapi" )
using namespace std;
DWORD GetModuleBase(LPSTR lpModuleName, DWORD dwProcessId)
{
MODULEENTRY32 lpModuleEntry = {0};
HANDLE hSnapShot = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwProcessId );
if(!hSnapShot)
return NULL;
lpModuleEntry.dwSize = sizeof(lpModuleEntry);
BOOL bModule = Module32First( hSnapShot, &lpModuleEntry );
while(bModule)
{
if(!strcmp( lpModuleEntry.szModule, lpModuleName ) )
{
CloseHandle( hSnapShot );
return (DWORD)lpModuleEntry.modBaseAddr;
}
bModule = Module32Next( hSnapShot, &lpModuleEntry );
}
CloseHandle( hSnapShot );
return NULL;
}
int main() {
HWND hWnd = FindWindow(0, "Calculator");
DWORD BaseAddr;
if(hWnd == 0){
MessageBox(0, "Error cannot find window.", "Error", MB_OK|MB_ICONERROR);
} else {
DWORD proccess_ID;
GetWindowThreadProcessId(hWnd, &proccess_ID);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, proccess_ID);
if(!hProcess){
MessageBox(0, "Could not open the process!", "Error!", MB_OK|MB_ICONERROR);
} else {
int newdata = 500;
BaseAddr = GetModuleBase("calc.exe",proccess_ID);
//GetModuleBase is always returning 0, so I am not getting the correct base address
DWORD newdatasize = sizeof(newdata);
if(WriteProcessMemory(hProcess, (LPVOID)0x002413FC, &newdata, newdatasize, NULL)){
cout << "Memory successfully written." << endl;
} else {
cout << "Memory failed to write." << endl;
}
CloseHandle(hProcess);
}
}
return 0;
}
Summary: I cannot get the correct base address using my GetModuleBase function, and I need to figure out what I am doing wrong so that I can get the correct base address for the "calc.exe" process.
You should read the modules like this:
#include <windows.h>
#include <TlHelp32.h>
#include <iostream>
//You don't have to use this function if you don't want to..
int strcompare(const char* One, const char* Two, bool CaseSensitive)
{
#if defined _WIN32 || defined _WIN64
return CaseSensitive ? strcmp(One, Two) : _stricmp(One, Two);
#else
return CaseSensitive ? strcmp(One, Two) : strcasecmp(One, Two);
#endif
}
//You read module information like this..
MODULEENTRY32 GetModuleInfo(std::uint32_t ProcessID, const char* ModuleName)
{
void* hSnap = nullptr;
MODULEENTRY32 Mod32 = {0};
if ((hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessID)) == INVALID_HANDLE_VALUE)
return Mod32;
Mod32.dwSize = sizeof(MODULEENTRY32);
while (Module32Next(hSnap, &Mod32))
{
if (!strcompare(ModuleName, Mod32.szModule, false))
{
CloseHandle(hSnap);
return Mod32;
}
}
CloseHandle(hSnap);
return {0};
}
int main()
{
//Change the process ID below..
BYTE* BaseAddr = GetModuleInfo(5172, "calc.exe").modBaseAddr;
std::cout<<"BASE ADDRESS: "<<(void*)BaseAddr<<"\n";
return 0;
}
EDIT: After further investigation, I found that Visual Studio was compiling for an x32 platform but calc.exe is an x64 process..
To get Visual Studio to compile for x64 you need to do the following:
Then click and select "NEW" from the following drop-down menu:
Next in the following drop down, select x64:
Save the settings and rebuild the project and it should work..
When unhandled exception occured i want to print a stacktrace instead of just terminating. I've tried to do that using SetUnhandledExceptionFilter:
SetUnhandledExceptionFilter(UnhandledException);
...
LONG WINAPI UnhandledException(LPEXCEPTION_POINTERS exceptionInfo)
{
printf("An exception occurred which wasn't handled!\nCode: 0x%08X\nAddress: 0x%08X",
exceptionInfo->ExceptionRecord->ExceptionCode,
exceptionInfo->ExceptionRecord->ExceptionAddress);
return EXCEPTION_EXECUTE_HANDLER;
}
This code, i've found, works fine. However there are no addition information because ExceptionCode and ExceptionAddress are printed in system "Event Viewer" anyway.
If it is possible to print a full stack trace so I can determine the exact point where exception occured?
I've found this code https://code.google.com/p/m0d-s0beit-sa/source/browse/src/main.cpp?r=9ceb4fec21d647b169c72851d7882bef2b9c5a8a It partly solves my problem. Only method where exception occured is printed. But type of exception and line number is not printed.
Here's some stack-walk code for Windows I wrote some years ago. Here's the kind of output it produces:
Walking stack.
0 DebugBreak
1 ThreadFunc2 e:\c\source\stackwalk2a.cpp(72)
2 ThreadFunc1 e:\c\source\stackwalk2a.cpp(79)
3 TargetThread e:\c\source\stackwalk2a.cpp(86)
4 BaseThreadInitThunk
5 RtlUserThreadStart
End of stack walk.
The main thing that's missing is anything about the exception type. If you're talking about a native structured/vectored exception, I'm pretty sure that should be retrievable too. Retrieving types of C++ exceptions might be a little more difficult (but I'm not really sure -- it might be pretty easy).
#include <windows.h>
#include <winnt.h>
#include <string>
#include <vector>
#include <Psapi.h>
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <stdexcept>
#include <iterator>
#pragma comment(lib, "psapi.lib")
#pragma comment(lib, "dbghelp.lib")
// Some versions of imagehlp.dll lack the proper packing directives themselves
// so we need to do it.
#pragma pack( push, before_imagehlp, 8 )
#include <imagehlp.h>
#pragma pack( pop, before_imagehlp )
struct module_data {
std::string image_name;
std::string module_name;
void *base_address;
DWORD load_size;
};
typedef std::vector<module_data> ModuleList;
HANDLE thread_ready;
bool show_stack(std::ostream &, HANDLE hThread, CONTEXT& c);
DWORD __stdcall TargetThread( void *arg );
void ThreadFunc1();
void ThreadFunc2();
DWORD Filter( EXCEPTION_POINTERS *ep );
void *load_modules_symbols( HANDLE hProcess, DWORD pid );
int main( void ) {
DWORD thread_id;
thread_ready = CreateEvent( NULL, false, false, NULL );
HANDLE thread = CreateThread( NULL, 0, TargetThread, NULL, 0, &thread_id );
WaitForSingleObject( thread_ready, INFINITE );
CloseHandle(thread_ready);
return 0;
}
// if you use C++ exception handling: install a translator function
// with set_se_translator(). In the context of that function (but *not*
// afterwards), you can either do your stack dump, or save the CONTEXT
// record as a local copy. Note that you must do the stack dump at the
// earliest opportunity, to avoid the interesting stack-frames being gone
// by the time you do the dump.
DWORD Filter(EXCEPTION_POINTERS *ep) {
HANDLE thread;
DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
GetCurrentProcess(), &thread, 0, false, DUPLICATE_SAME_ACCESS);
std::cout << "Walking stack.";
show_stack(std::cout, thread, *(ep->ContextRecord));
std::cout << "\nEnd of stack walk.\n";
CloseHandle(thread);
return EXCEPTION_EXECUTE_HANDLER;
}
void ThreadFunc2() {
__try { DebugBreak(); }
__except (Filter(GetExceptionInformation())) { }
SetEvent(thread_ready);
}
void ThreadFunc1(void (*f)()) {
f();
}
// We'll do a few levels of calls from our thread function so
// there's something on the stack to walk...
//
DWORD __stdcall TargetThread(void *) {
ThreadFunc1(ThreadFunc2);
return 0;
}
class SymHandler {
HANDLE p;
public:
SymHandler(HANDLE process, char const *path=NULL, bool intrude = false) : p(process) {
if (!SymInitialize(p, path, intrude))
throw(std::logic_error("Unable to initialize symbol handler"));
}
~SymHandler() { SymCleanup(p); }
};
#ifdef _M_X64
STACKFRAME64 init_stack_frame(CONTEXT c) {
STACKFRAME64 s;
s.AddrPC.Offset = c.Rip;
s.AddrPC.Mode = AddrModeFlat;
s.AddrStack.Offset = c.Rsp;
s.AddrStack.Mode = AddrModeFlat;
s.AddrFrame.Offset = c.Rbp;
s.AddrFrame.Mode = AddrModeFlat;
return s;
}
#else
STACKFRAME64 init_stack_frame(CONTEXT c) {
STACKFRAME64 s;
s.AddrPC.Offset = c.Eip;
s.AddrPC.Mode = AddrModeFlat;
s.AddrStack.Offset = c.Esp;
s.AddrStack.Mode = AddrModeFlat;
s.AddrFrame.Offset = c.Ebp;
s.AddrFrame.Mode = AddrModeFlat;
return s;
}
#endif
void sym_options(DWORD add, DWORD remove=0) {
DWORD symOptions = SymGetOptions();
symOptions |= add;
symOptions &= ~remove;
SymSetOptions(symOptions);
}
class symbol {
typedef IMAGEHLP_SYMBOL64 sym_type;
sym_type *sym;
static const int max_name_len = 1024;
public:
symbol(HANDLE process, DWORD64 address) : sym((sym_type *)::operator new(sizeof(*sym) + max_name_len)) {
memset(sym, '\0', sizeof(*sym) + max_name_len);
sym->SizeOfStruct = sizeof(*sym);
sym->MaxNameLength = max_name_len;
DWORD64 displacement;
if (!SymGetSymFromAddr64(process, address, &displacement, sym))
throw(std::logic_error("Bad symbol"));
}
std::string name() { return std::string(sym->Name); }
std::string undecorated_name() {
std::vector<char> und_name(max_name_len);
UnDecorateSymbolName(sym->Name, &und_name[0], max_name_len, UNDNAME_COMPLETE);
return std::string(&und_name[0], strlen(&und_name[0]));
}
};
bool show_stack(std::ostream &os, HANDLE hThread, CONTEXT& c) {
HANDLE process = GetCurrentProcess();
int frame_number=0;
DWORD offset_from_symbol=0;
IMAGEHLP_LINE64 line = {0};
SymHandler handler(process);
sym_options(SYMOPT_LOAD_LINES | SYMOPT_UNDNAME);
void *base = load_modules_symbols(process, GetCurrentProcessId());
STACKFRAME64 s = init_stack_frame(c);
line.SizeOfStruct = sizeof line;
IMAGE_NT_HEADERS *h = ImageNtHeader(base);
DWORD image_type = h->FileHeader.Machine;
do {
if (!StackWalk64(image_type, process, hThread, &s, &c, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL))
return false;
os << std::setw(3) << "\n" << frame_number << "\t";
if ( s.AddrPC.Offset != 0 ) {
std::cout << symbol(process, s.AddrPC.Offset).undecorated_name();
if (SymGetLineFromAddr64( process, s.AddrPC.Offset, &offset_from_symbol, &line ) )
os << "\t" << line.FileName << "(" << line.LineNumber << ")";
}
else
os << "(No Symbols: PC == 0)";
++frame_number;
} while (s.AddrReturn.Offset != 0);
return true;
}
class get_mod_info {
HANDLE process;
static const int buffer_length = 4096;
public:
get_mod_info(HANDLE h) : process(h) {}
module_data operator()(HMODULE module) {
module_data ret;
char temp[buffer_length];
MODULEINFO mi;
GetModuleInformation(process, module, &mi, sizeof(mi));
ret.base_address = mi.lpBaseOfDll;
ret.load_size = mi.SizeOfImage;
GetModuleFileNameEx(process, module, temp, sizeof(temp));
ret.image_name = temp;
GetModuleBaseName(process, module, temp, sizeof(temp));
ret.module_name = temp;
std::vector<char> img(ret.image_name.begin(), ret.image_name.end());
std::vector<char> mod(ret.module_name.begin(), ret.module_name.end());
SymLoadModule64(process, 0, &img[0], &mod[0], (DWORD64)ret.base_address, ret.load_size);
return ret;
}
};
void *load_modules_symbols(HANDLE process, DWORD pid) {
ModuleList modules;
DWORD cbNeeded;
std::vector<HMODULE> module_handles(1);
EnumProcessModules(process, &module_handles[0], module_handles.size() * sizeof(HMODULE), &cbNeeded);
module_handles.resize(cbNeeded/sizeof(HMODULE));
EnumProcessModules(process, &module_handles[0], module_handles.size() * sizeof(HMODULE), &cbNeeded);
std::transform(module_handles.begin(), module_handles.end(), std::back_inserter(modules), get_mod_info(process));
return modules[0].base_address;
}
I have a probelm :( i wanna make a program wich gives a random number :) i don't want use rand() function :) i wanna make one for me then turn it to a function ;) for educational purpose :)
but i have a problem :( see my code :)
#include <stdio.h>
#include <iostream>
#include <conio.h>
#include <windows.h>
#define MIN 0
#define MAX 99999
using namespace std;
typedef struct _RANDOM_INFO{
DWORD random;
DWORD min;
DWORD max;
} RANDOM_INFO, * LPRANDOM_INFO;
void Error(LPSTR lpErrorMessage){
cout << lpErrorMessage << endl;
exit(EXIT_FAILURE);
}
void GetRandom(LPVOID lpParam){
DWORD dwListSize = 10000, min = 0, max = 99999;
LPDWORD lpRandom = (LPDWORD)lpParam;
LPSTR lpFileSelf, lpKernel, lpNtdll;
HMODULE hFileSelf = NULL, hKernel = NULL, hNtdll = NULL;
hFileSelf = (HMODULE) GetModuleHandle(NULL);
hKernel = (HMODULE) GetModuleHandle("kernel.dll");
hNtdll = (HMODULE) GetModuleHandle("ntdll.dll");
lpFileSelf = (LPSTR) hFileSelf;
lpKernel = (LPSTR) hKernel;
lpNtdll = (LPSTR) hNtdll;
while(1){
DWORD i;
for(i = 0; i <= dwListSize; i++){
*lpRandom = (DWORD)lpFileSelf[i];
}
i = 0;
}
return;
}
int main(int argc, char **argv)
{
DWORD random = 0;
DWORD getRandomThreadId = 0;
HANDLE hGetRandomThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)GetRandom, &random, 0, &getRandomThreadId);
if(hGetRandomThread == INVALID_HANDLE_VALUE)
Error("Cannot make a random list.");
getch();
cout << random << endl;
Sleep(1500);
return 0;
}
The variable should get a value when and print it but i always i get 0 and a windows error can someone tell me why??? and another problem when i try to use the variable hKernel in the GetRandom function i get an error too :( but it works fine whith hFileSelf and hNtdll !!!! is kernel protected from reading???
Note : this is not a random number generation :) its just a way to get a number from the memory when the user click on the enter on his keyboard :), and its not always the same time for all users so its not always the same pointer in memory :) i hope u understand what i want do :) sorry for my bad englush :) just help me to fix the problem :)
Thank u :)
Your GetRandom() function does not have the correct signature for a CreateThread() callback procedure. Try this instead:
#include <stdio.h>
#include <iostream>
#include <conio.h>
#include <windows.h>
#define MIN 0
#define MAX 99999
using namespace std;
typedef struct _RANDOM_INFO
{
DWORD random;
DWORD min;
DWORD max;
} RANDOM_INFO, * LPRANDOM_INFO;
void Error(LPSTR lpErrorMessage)
{
cout << lpErrorMessage << endl;
exit(EXIT_FAILURE);
}
HMODULE hFileSelf = (HMODULE) GetModuleHandle(NULL);
DWORD WINAPI GetRandomThreadProc(LPVOID lpParam)
{
LPDWORD lpRandom = (LPDWORD) lpParam;
DWORD dwListSize = 10000, min = 0, max = 99999;
LPBYTE lpFileSelf = (LPBYTE) hFileSelf;
while (1)
{
for (DWORD i = 0; i <= dwListSize; ++i)
{
*lpRandom = (DWORD) lpFileSelf[i];
}
Sleep(0);
}
return 0;
}
int main(int argc, char **argv)
{
DWORD dwRandom = 0;
DWORD dwRandomThreadId = 0;
HANDLE hGetRandomThread = CreateThread(NULL, 0, &GetRandomThreadProc, &dwRandom, 0, &dwRandomThreadId);
if (hGetRandomThread == INVALID_HANDLE_VALUE)
Error("Cannot make a random list.");
do
{
getch();
cout << dwRandom << endl;
}
while (WaitForSingleObject(hGetRandomThread, 0) == WAIT_TIMEOUT);
CloseHandle(hGetRandomThread);
return 0;
}
i wanna make a program wich gives a random number
What you are doing has nothing to do with random number generation.
This is one way to do it:
Linear Congruential Generator