I stumbled upon a tutorial about dll injection in c. When I run my code, it gives me a Debug Assertion Failed error when I use the CreateRemoteThread() function in my code.
I use Visual Studio Express 2015 on Windows 10
The Error:
#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
char* buffer = "C:\\inject2.dll";
//Get the process handle passing in the process ID
int procID = 9872;
HANDLE process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procID);
if (process == NULL) {
printf("Error: the specified process couldn't be found\n");
}
//Get the address of the LoadLibrary function
LPVOID addr = (LPVOID)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryA");
if (addr == NULL) {
printf("Error: the LoadLibraryA function was not found inside kernel32.dll library.\n");
}
//Allocate new memory region inside the process's address space
LPVOID arg = (LPVOID)VirtualAllocEx(process, NULL, strlen(buffer), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if (arg == NULL)
{
printf("Error: the memory could not be allocated inside the chosen process.\n");
}
//Write the argument to LoadLibraryA to the process's newly allocated memory region
int n = WriteProcessMemory(process, arg, buffer, strlen(buffer), NULL);
if (n == 0) {
printf("Error: there were not bytes written to the process's address space.\n");
}
//Inject our DLL into the process's address space
HANDLE threadID = CreateRemoteThread(process, NULL, 0, (LPTHREAD_START_ROUTINE)addr, arg, NULL, NULL);
if (threadID == NULL)
{
printf("Error: the remote thread could not be created.\n");
}
else
{
printf("Success: the remote thread was succesfully created.\n");
}
//Close the handle to the process because we have already injected the DLL
CloseHandle(process);
getchar();
return 0;
}
If you're using the DLL from the link you supplied, it's probably failing because it's attempting to write to the root of the system drive ("C:\\temp.txt",). Change this path to something your target process can write to.
Related
I am trying to write a DLL injector to perform a DLL injector on a calculator process.
I wrote the DLL injector program in C and the DLL but the injector dosent inject the DLL or any other DLL (I tried to take some random windows DLL that the calculator doesn't use).
#include <stdio.h>
#include <Windows.h>
int main() {
LPCSTR dllpath = "C:\\Users\\......\\Dll1.dll";
printf("#### Starting ####\n");
printf("step 1: attaching the target process memory\n");
HANDLE hProcess = OpenProcess(
PROCESS_ALL_ACCESS,
FALSE,
6456 // target process id
);
if (hProcess != NULL) {
printf("step 2: allocate the target memory process\n");
LPVOID dllPathMemoryAddr = VirtualAllocEx(
hProcess,
NULL,
strlen(dllpath),
MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE
);
if (dllPathMemoryAddr != NULL) {
printf("step 3: write to the process memory\n");
BOOL succeededWriting = WriteProcessMemory(
hProcess,
dllPathMemoryAddr,
dllpath,
strlen(dllpath),
NULL
);
if (succeededWriting) {
printf("step 4: execute.\n");
FARPROC loadLibAddr = GetProcAddress(
GetModuleHandle(TEXT("kernel32.dll")),
"LoadLibraryA"
);
HANDLE rThread = CreateRemoteThread(
hProcess,
NULL,
0,
(LPTHREAD_START_ROUTINE)loadLibAddr,
dllPathMemoryAddr,
0,
NULL
);
}
}
CloseHandle(hProcess);
}
return TRUE;
}
after running the injector I get this output:
#### Starting ####
step 1: attaching the target process memory
step 2: allocate the target memory process
step 3: write to the process memory
step 4: execute.
after that, I am still unable to see in process explorer the new DLL.
You are calling GetProcAddress() to get the address of LoadLibraryA(), this is returning the address of LoadLibraryA in your local process not the injected one. This is not guaranteed to be correct in the external process. You do not need to get the address manually, CreateRemoteThread will resolve the address for you.
Here is a very simple injector example that will explain how to do it
#include <iostream>
#include <Windows.h>
#include <TlHelp32.h>
DWORD GetPid(char * targetProcess)
{
HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snap && snap != INVALID_HANDLE_VALUE)
{
PROCESSENTRY32 pe;
pe.dwSize = sizeof(pe);
if (Process32First(snap, &pe))
{
do
{
if (!_stricmp(pe.szExeFile, targetProcess))
{
CloseHandle(snap);
return pe.th32ProcessID;
}
} while (Process32Next(snap, &pe));
}
}
return 0;
}
int main()
{
char * dllpath = "C:\\Users\\me\\Desktop\\dll.dll";
char * processToInject = "csgo.exe";
long pid = 0;
while (!pid)
{
pid = GetPid(processToInject);
Sleep(10);
}
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
if (hProc && hProc != INVALID_HANDLE_VALUE)
{
void * loc = VirtualAllocEx(hProc, 0, MAX_PATH, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
WriteProcessMemory(hProc, loc, dllpath, strlen(dllpath) + 1, 0);
HANDLE hThread = CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)LoadLibraryA, loc, 0, 0);
CloseHandle(hThread);
}
CloseHandle(hProc);
return 0;
}
I found the problem. I compiled the DLL as 64 but accidentally compiled the DLL injector has complied as 32 bit.
I am writing a simple application on C that uses shared memory but I cannot run it anymore as it says:
shmat: Cannot allocate memory
I am using this script to free my memory but doesn't seem to work.
This is a screenshot of my processes:
This is the application code:
/* Shared Memory IPC creates a mamory space and send contendt to it while the other process can read from it.
Our implementation works like this:
1. First run the application by passing as a argument the value you want to send to the shared memory. Example: ./ipc_sharedmem.o 4
2. Run the appliation again to read from the shared memory (which is a new process, of course) wihout sending any arguments. Exmaple: ./ipc_sharedmem.o
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define SHM_SIZE 1024 /* make it a 1K shared memory segment */
int main(int argc, char *argv[])
{
key_t key;
int shared_mem_mid;
char *data;
struct timeval t1, t2, t3, t4;
if (argc > 2) {
fprintf(stderr, "usage: shmdemo [data_to_write]\n");
exit(1);
}
/* make the key: */
if ((key = ftok("mach.c", 'R')) == -1) {
perror("ftok");
exit(1);
}
/* connect to (and possibly create) the segment: */
if ((shared_mem_mid = shmget(key, SHM_SIZE, 0644 | IPC_CREAT)) == -1) {
perror("shmget");
exit(1);
}
/* attach to the segment to get a pointer to it: */
gettimeofday(&t1, NULL);
data = (char *) shmat(shared_mem_mid, (void *)0, 0);
gettimeofday(&t2, NULL);
if (data == (char *)(-1)) {
perror("shmat");
exit(1);
}
printf("Time to read the message from sharem memory: %g \n", (t2.tv_sec + t2.tv_usec/1000000.0)-(t1.tv_sec + t1.tv_usec/1000000.0));
/* read or modify the segment, based on the command line: */
if (argc == 2) {
printf("writing to segment: \"%s\"\n", argv[1]);
gettimeofday(&t3, NULL);
strncpy(data, argv[1], SHM_SIZE);
gettimeofday(&t4, NULL);
printf("Time to send data to shared memory: %g \n", (t4.tv_sec + t4.tv_usec/1000000.0)-(t3.tv_sec + t3.tv_usec/1000000.0));
} else{
printf("segment contains: \"%s\"\n", data);
}
/* detach from the segment: */
if (shmdt(data) == -1) {
perror("shmdt");
exit(1);
}
return 0;
}
Any idea?
Your shared memory segments are marked as to be destroyed but still have process(es) attached to them.
Per the source code, the nattach column is 2 and the status is "dest", meaning the shared memory segments have 2 attachments and are marked to be destroyed once the last attached process detaches from the segment.
You need to either have the process(es) attached to the segments call shmdt() to detach from the shared memory segments, or you need kill those process(es). Once you do that the segments will be destroyed.
Have you tried (as root):
$ sync; echo 3 > /proc/sys/vm/drop_caches
Not sure this will free your shared memory, but you can try.
If you want to see an example, here goes a gist: https://gist.github.com/hudsantos/7fec7d9c34cc472b7f98
I am dynamically loading a library with dlopen, then closing it with dlclose. I expected all library resources to be freed once dlclose completed, but there are still open file descriptors from the library after the dlclose call. I am wondering how to make sure a library is unloaded in the middle of program execution, such that it cleans up all of its resources.
My code is below:
#include <CL/cl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dlfcn.h>
#include <string.h>
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#define MAX_PATH_LENGTH 80
int deviceQ()
{
cl_int ret;
void * libHandle = dlopen("/usr/lib64/libOpenCL.so", RTLD_LAZY);
cl_int (* clGetPlatformIDs)(cl_uint, cl_platform_id*, cl_uint*) = dlsym(
libHandle, "clGetPlatformIDs"
);
cl_int (* clGetDeviceIDs)(cl_platform_id, cl_device_type, cl_uint, cl_device_id*, cl_uint*) =
dlsym(libHandle, "clGetDeviceIDs");
/********************** PREAMBLE **************************************/
cl_device_id device_id = NULL;
cl_platform_id platform_id = NULL;
cl_uint ret_num_devices;
cl_uint ret_num_platforms;
ret = clGetPlatformIDs(1, &platform_id, &ret_num_platforms);
if (ret != CL_SUCCESS) {
perror("Failed to get platform IDs");
} else if (ret_num_platforms != 1) {
fprintf(stderr, "Number of platforms returned is %d\n", ret_num_platforms);
exit(1);
}
printf("Read platform IDs\n");
ret = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU, 1, &device_id,
&ret_num_devices);
if (ret != CL_SUCCESS) {
perror("Failed to get device IDs");
} else if (ret_num_devices != 1) {
fprintf(stderr, "Number of returned devices is %d\n", ret_num_devices);
exit(1);
}
printf("Read device IDs\n");
/********************** PREAMBLE **************************************/
/***************** RELEASE AND FREE ****************************/
dlclose(libHandle);
/***************** RELEASE AND FREE ****************************/
return 0;
}
size_t closeFileDescriptors(void ** arr) {
// step 1 - get PID
pid_t pid = getpid();
//printf("PID is %d\n", pid);
char path[MAX_PATH_LENGTH];
memset(path, '\0', MAX_PATH_LENGTH);
sprintf(path, "/proc/%d/fd", pid);
int fd;
DIR * d = opendir(path);
struct dirent *dir;
struct stat s;
char dirPath[MAX_PATH_LENGTH];
char realPath[MAX_PATH_LENGTH];
size_t index = 0;
if (d) {
while ((dir = readdir(d)) != NULL) {
if (strcmp(dir->d_name, ".") != 0 &&
strcmp(dir->d_name, "..") != 0) {
fd = atoi(dir->d_name);
if (fstat(fd, &s) != 0) {
perror("fstat failed");
}
memset(dirPath, '\0', MAX_PATH_LENGTH);
strcpy(dirPath, path);
strcat(dirPath, "/");
strcat(dirPath, dir->d_name);
#ifdef S_IFLNK
if (s.st_mode & S_IFLNK) {
#else
if (S_ISLNK(s.st_mode)) {
#endif
memset(realPath, '\0', MAX_PATH_LENGTH);
#ifdef readlink
readlink(dirPath, realPath, MAX_PATH_LENGTH);
printf("%s -> %s\n", dirPath, realPath);
#else
printf("[readlink not defined] %s\n", dirPath);
#endif
} else {
printf("Not link: %s (proceeding anyway)\n", dirPath);
//printf("Not link: %s (ignoring)\n", dirPath);
//continue;
}
if (fd > 2) {
//int fdFlags = fcntl(fd, F_GETFD);
int fdFlags = fcntl(fd, F_GETFL);
if (fdFlags == -1) {
perror("fcntl failed");
}
//off_t offset = lseek(fd, 0, SEEK_CUR);
off_t offset = 0;
if (offset == -1) {
perror("lseek failed");
}
if (arr != NULL) {
/*
arr[index] = (fileData *) malloc(sizeof (fileData));
arr[index]->flags = fdFlags;
arr[index]->offset = offset;
arr[index]->fd = fd;
strcpy(arr[index]->fdPath, realPath);*/
}
index++;
// ignore stdin, stdout, stderr
printf("Closing FD %d (flags %d, offset %zd)\n",
fd, fdFlags, offset);
close(fd);
}
}
}
closedir(d);
} else {
fprintf(stderr, "Could not open directory %s\n", path);
}
return index;
}
int main () {
deviceQ();
printf("=> Closing open file descriptors\n");
closeFileDescriptors (NULL);
deviceQ();
return 0;
}
Your expectation is wrong. When you call dlclose(3), only the "plugin" (actually shared object) is "closed" (actually, may be munmap-ed), but not the resources (in particular the file descriptors, and possibly heap allocated memory) it has used.
In addition, on Linux specifically, dlclose is calling the so-called destructor functions of the plugin (those declared with __attribute__((destructor)), read about function attributes in GCC).
If you are coding a shared library, you might design it so that some resources are released at dlclose time (by having appropriate finalizations run thru destructor functions). In general, it is not easily possible (and it should be a documented convention).
Resources like address space in virtual memory (obtained by mmap(2) etc...) and file descriptors (obtained by open(2), socket(2), pipe(2) etc etc...) are global (and common) to the entire process.
So it would be possible (and legitimate, if documented) to acquire some resource (e.g. open some file descriptor) in one shared library and to release it in another one (or in the main program).
Since a resource "belongs" to the entire process, it makes no sense to speak of releasing the resources acquired by a library.
So your closeFileDescriptors is quite probably a huge mistake (and it probably leaks some other resources).
(IIRC, OpenCL API has some way to release its resources, e.g. devices, contexts, kernels, etc.... But I forgot the ugly details; see clReleaseContext, clReleaseMemObject and many more, including some implementation specific ones.)
Reading more about garbage collection would probably widen your mind.
Read also Drepper's paper: How To Write a Shared Library & credentials(7)
If you absolutely need to release OpenCL related resources early, a more sensible way might be to start a different child process dedicated to OpenCL things, and use clever IPC mechanisms (e.g. pipe(7), shm_overview(7), sem_overview(7), etc...) then terminate (properly) that child process once your OpenCL stuff is done. You take advantage of the fact that the kernel is cleaning all the resources used by a defunct process (don't forget to wait... it -e.g. using waitpid(2)- to avoid having zombie processes). If you are not familiar with all that, read Advanced Linux Programming first.
I'm trying to read memory from a process (calc.exe). But I'm hitting "Could not read memory" message. Where is my mistake?
int main() {
HWND handle = FindWindow(0, TEXT("Calculadora"));
if (!handle) {
msg("Could not find window");
return 0;
}
DWORD id;
GetWindowThreadProcessId(handle, &id);
HANDLE proc = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, id);
if (!proc) {
msg("Could not open process");
return 0;
}
char buffer[128];
if (ReadProcessMemory(proc, 0, &buffer, 128, NULL)) {
msg("yes!!");
}
else {
msg("Could not read memory");
}
CloseHandle(proc);
}
You are attempting to read address 0 in the target process. That will always fail. You need to read from an address which is meaningful in the virtual address space of the target process.
Note that in order to call ReadProcessMemory you only need PROCESS_VM_READ. That's not the problem here, but I thought I would point it out for sake of completeness.
I have a bit of an issue with one of my projects.
I have been trying to find a well documented example of using shared memory with fork() but to no success.
Basically the scenario is that when the user starts the program, I need to store two values in shared memory: current_path which is a char* and a file_name which is also char*.
Depending on the command arguments, a new process is kicked off with fork() and that process needs to read and modify the current_path variable stored in shared memory while the file_name variable is read only.
Is there a good tutorial on shared memory with example code (if possible) that you can direct me to?
There are two approaches: shmget and mmap. I'll talk about mmap, since it's more modern and flexible, but you can take a look at man shmget (or this tutorial) if you'd rather use the old-style tools.
The mmap() function can be used to allocate memory buffers with highly customizable parameters to control access and permissions, and to back them with file-system storage if necessary.
The following function creates an in-memory buffer that a process can share with its children:
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
void* create_shared_memory(size_t size) {
// Our memory buffer will be readable and writable:
int protection = PROT_READ | PROT_WRITE;
// The buffer will be shared (meaning other processes can access it), but
// anonymous (meaning third-party processes cannot obtain an address for it),
// so only this process and its children will be able to use it:
int visibility = MAP_SHARED | MAP_ANONYMOUS;
// The remaining parameters to `mmap()` are not important for this use case,
// but the manpage for `mmap` explains their purpose.
return mmap(NULL, size, protection, visibility, -1, 0);
}
The following is an example program that uses the function defined above to allocate a buffer. The parent process will write a message, fork, and then wait for its child to modify the buffer. Both processes can read and write the shared memory.
#include <string.h>
#include <unistd.h>
int main() {
char parent_message[] = "hello"; // parent process will write this message
char child_message[] = "goodbye"; // child process will then write this one
void* shmem = create_shared_memory(128);
memcpy(shmem, parent_message, sizeof(parent_message));
int pid = fork();
if (pid == 0) {
printf("Child read: %s\n", shmem);
memcpy(shmem, child_message, sizeof(child_message));
printf("Child wrote: %s\n", shmem);
} else {
printf("Parent read: %s\n", shmem);
sleep(1);
printf("After 1s, parent read: %s\n", shmem);
}
}
Here is an example for shared memory :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define SHM_SIZE 1024 /* make it a 1K shared memory segment */
int main(int argc, char *argv[])
{
key_t key;
int shmid;
char *data;
int mode;
if (argc > 2) {
fprintf(stderr, "usage: shmdemo [data_to_write]\n");
exit(1);
}
/* make the key: */
if ((key = ftok("hello.txt", 'R')) == -1) /*Here the file must exist */
{
perror("ftok");
exit(1);
}
/* create the segment: */
if ((shmid = shmget(key, SHM_SIZE, 0644 | IPC_CREAT)) == -1) {
perror("shmget");
exit(1);
}
/* attach to the segment to get a pointer to it: */
if ((data = shmat(shmid, NULL, 0)) == (void *)-1) {
perror("shmat");
exit(1);
}
/* read or modify the segment, based on the command line: */
if (argc == 2) {
printf("writing to segment: \"%s\"\n", argv[1]);
strncpy(data, argv[1], SHM_SIZE);
} else
printf("segment contains: \"%s\"\n", data);
/* detach from the segment: */
if (shmdt(data) == -1) {
perror("shmdt");
exit(1);
}
return 0;
}
Steps :
Use ftok to convert a pathname and a project identifier to a System V IPC key
Use shmget which allocates a shared memory segment
Use shmat to attache the shared memory segment identified by shmid to the address space of the calling process
Do the operations on the memory area
Detach using shmdt
These are includes for using shared memory
#include<sys/ipc.h>
#include<sys/shm.h>
int shmid;
int shmkey = 12222;//u can choose it as your choice
int main()
{
//now your main starting
shmid = shmget(shmkey,1024,IPC_CREAT);
// 1024 = your preferred size for share memory
// IPC_CREAT its a flag to create shared memory
//now attach a memory to this share memory
char *shmpointer = shmat(shmid,NULL);
//do your work with the shared memory
//read -write will be done with the *shmppointer
//after your work is done deattach the pointer
shmdt(&shmpointer, NULL);
try this code sample, I tested it, source: http://www.makelinux.net/alp/035
#include <stdio.h>
#include <sys/shm.h>
#include <sys/stat.h>
int main ()
{
int segment_id;
char* shared_memory;
struct shmid_ds shmbuffer;
int segment_size;
const int shared_segment_size = 0x6400;
/* Allocate a shared memory segment. */
segment_id = shmget (IPC_PRIVATE, shared_segment_size,
IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR);
/* Attach the shared memory segment. */
shared_memory = (char*) shmat (segment_id, 0, 0);
printf ("shared memory attached at address %p\n", shared_memory);
/* Determine the segment's size. */
shmctl (segment_id, IPC_STAT, &shmbuffer);
segment_size = shmbuffer.shm_segsz;
printf ("segment size: %d\n", segment_size);
/* Write a string to the shared memory segment. */
sprintf (shared_memory, "Hello, world.");
/* Detach the shared memory segment. */
shmdt (shared_memory);
/* Reattach the shared memory segment, at a different address. */
shared_memory = (char*) shmat (segment_id, (void*) 0x5000000, 0);
printf ("shared memory reattached at address %p\n", shared_memory);
/* Print out the string from shared memory. */
printf ("%s\n", shared_memory);
/* Detach the shared memory segment. */
shmdt (shared_memory);
/* Deallocate the shared memory segment. */
shmctl (segment_id, IPC_RMID, 0);
return 0;
}
Here's a mmap example:
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
/*
* pvtmMmapAlloc - creates a memory mapped file area.
* The return value is a page-aligned memory value, or NULL if there is a failure.
* Here's the list of arguments:
* #mmapFileName - the name of the memory mapped file
* #size - the size of the memory mapped file (should be a multiple of the system page for best performance)
* #create - determines whether or not the area should be created.
*/
void* pvtmMmapAlloc (char * mmapFileName, size_t size, char create)
{
void * retv = NULL;
if (create)
{
mode_t origMask = umask(0);
int mmapFd = open(mmapFileName, O_CREAT|O_RDWR, 00666);
umask(origMask);
if (mmapFd < 0)
{
perror("open mmapFd failed");
return NULL;
}
if ((ftruncate(mmapFd, size) == 0))
{
int result = lseek(mmapFd, size - 1, SEEK_SET);
if (result == -1)
{
perror("lseek mmapFd failed");
close(mmapFd);
return NULL;
}
/* Something needs to be written at the end of the file to
* have the file actually have the new size.
* Just writing an empty string at the current file position will do.
* Note:
* - The current position in the file is at the end of the stretched
* file due to the call to lseek().
* - The current position in the file is at the end of the stretched
* file due to the call to lseek().
* - An empty string is actually a single '\0' character, so a zero-byte
* will be written at the last byte of the file.
*/
result = write(mmapFd, "", 1);
if (result != 1)
{
perror("write mmapFd failed");
close(mmapFd);
return NULL;
}
retv = mmap(NULL, size,
PROT_READ | PROT_WRITE, MAP_SHARED, mmapFd, 0);
if (retv == MAP_FAILED || retv == NULL)
{
perror("mmap");
close(mmapFd);
return NULL;
}
}
}
else
{
int mmapFd = open(mmapFileName, O_RDWR, 00666);
if (mmapFd < 0)
{
return NULL;
}
int result = lseek(mmapFd, 0, SEEK_END);
if (result == -1)
{
perror("lseek mmapFd failed");
close(mmapFd);
return NULL;
}
if (result == 0)
{
perror("The file has 0 bytes");
close(mmapFd);
return NULL;
}
retv = mmap(NULL, size,
PROT_READ | PROT_WRITE, MAP_SHARED, mmapFd, 0);
if (retv == MAP_FAILED || retv == NULL)
{
perror("mmap");
close(mmapFd);
return NULL;
}
close(mmapFd);
}
return retv;
}