The following code is supposed to print out the names of all the sections in the specified exe (c:\linked list.exe in this case), but it produces some bizarre output.
#include<iostream>
#include<Windows.h>
#include<stdio.h>
#include<WinNT.h>
int main()
{
FILE *fp;
int i;
if((fp = fopen("c:\\Linked List.exe","rb"))==NULL)
std::cout<<"unable to open";
IMAGE_DOS_HEADER imdh;
fread(&imdh,sizeof(imdh),1,fp);
IMAGE_NT_HEADERS imnth;
fread(&imnth,sizeof(imnth),1,fp);
IMAGE_SECTION_HEADER *pimsh;
pimsh = (IMAGE_SECTION_HEADER *)malloc(sizeof(IMAGE_SECTION_HEADER) * imnth.FileHeader.NumberOfSections);
fread(pimsh,sizeof(IMAGE_SECTION_HEADER),imnth.FileHeader.NumberOfSections,fp);
for(i=0;i<imnth.FileHeader.NumberOfSections;i++)
{
printf("%s\n",pimsh->Name);
pimsh++;
}
}
the issue with you code, is which you are not reading for the correct location the IMAGE_NT_HEADERS struture, you must set the offset of the file to the value of imdh.e_lfanew using fseek(fp, imdh.e_lfanew, 0); and then read the IMAGE_NT_HEADERS record.
Try this modified code.
#include "stdafx.h"
#include<iostream>
#include<Windows.h>
#include<stdio.h>
#include<WinNT.h>
int main()
{
FILE *fp;
int i;
if((fp = fopen("c:\\Linked List.exe","rb"))==NULL)
std::cout<<"unable to open";
IMAGE_DOS_HEADER imdh;
fread(&imdh,sizeof(imdh),1,fp);
//set the pointer of the file to the location of the IMAGE_NT_HEADERS record
fseek(fp, imdh.e_lfanew, 0);
IMAGE_NT_HEADERS imnth;
fread(&imnth,sizeof(imnth),1,fp);
IMAGE_SECTION_HEADER *pimsh;
pimsh = (IMAGE_SECTION_HEADER *)malloc(sizeof(IMAGE_SECTION_HEADER) * imnth.FileHeader.NumberOfSections);
fread(pimsh,sizeof(IMAGE_SECTION_HEADER),imnth.FileHeader.NumberOfSections,fp);
for(i=0;i<imnth.FileHeader.NumberOfSections;i++)
{
printf("%s\n",pimsh->Name);
pimsh++;
}
getchar();
}
Also take a look to these articles about the PE Format.
An In-Depth Look into the Win32 Portable Executable File Format
Peering Inside the PE: A Tour of the Win32 Portable Executable File Format
Yes it is possible to remove the DOS Stub from an Image. If this stub exists, the Windows Loader ignores it. If this stub does not exist, the Windows Loader is happy with it.
Related
I'm attempting to read a PE file in C.
I have code MZ and then, I don't know to code e_lfanew.
#include <stdio.h>
#include <Windows.h>
int main()
{
errno_t err;
FILE *fp = NULL;
char *buffer;
err = fopen_s(&fp, "D:\\pe.exe", "rb");
printf("----------dos header---------- \n");
buffer = new char[3]; // malloc: cap phat bo nho//
memset(buffer, 0x0, sizeof(char)* 3); // memset: gan gia tri cho buffer//
fread(buffer, 2 * sizeof(char), 1, fp);
printf("e_magic: %s \n", buffer);
}
Also, I am aware this is possible via the Win32 API; however, I want to learn from this and do it myself.
Typically one would define a struct called DOS_Header and read the complete struct from the file. That struct then has a field e_lfanew which can directly be accessed without pointer arithmetics etc.
e_lfanew then points to the PE signature (PE\0\0), followed by the COFF header. Then the story repeats: create a struct called COFF_Header and read the complete struct from the file...
As #thomas weller said you need to typecast your buffer to IMAGE_DOS_HEADER.
The last field tells you where the PE header is, then read that offset and typecast the buffer to IMAGE_NT_HEADER. The other way is to just map the file in and typecast the relevant buffers memory.
To get details about any header information you can directly fill it to the structure for example
IMAGE_DOS_HEADER imgDosHdr = {0};
FILE *fp = fopen("Path_to_Pe","rb");
if(fp == NULL) return;
fseek(fp,0,SEEK_SET);
fread(&imgDosHdr,1,sizeof(IMAGE_DOS_HEADER),fp);
fclose(fp);
Hence you can get all the details of PE file Header by Setting the
fseek.
I have declared a function in the c++ file as stated in the documentation and called it in the .ned file. But it gives the following error.
error:expected constructor, destructor, or type conversion before ‘(’ token Define_Function(dijkstra, 1);
The following is my c++ file.
#include <omnetpp.h>
#include "stdio.h"
#include "Node.h"
#include "cdelaychannel.h"
Define_Function(dijkstra, 1);
double dijkstra(double start = 1){
....
....
}
In my network description file, I've called the function.
package myproject;
#license(LGPL);
dijkstra(1.0);
Why is it giving me the error?
If you want to create a function for using it in NED files, you have to do it as described in OMNeT++ Manual. An example could be the following:
static cNEDValue ned_foo(cComponent *context, cNEDValue argv[], int argc)
int a = (long) argv[0];
int b = (long) argv[1];
return a*b;
}
Define_NED_Function(ned_foo,"int ned_foo(int a, int b)");
I'm having some problems with my code. I get segmentation code error after compiling my program. I want to build simply download tool so i'm using the simplest ideas for it.(User enters the url and program download file into users desktop). Could you give me some tips how to make this program work or how to convert it to better one (more demanding code with better results).
#define CURL_STATICLIB
#include <stdio.h>
#include <curl/curl.h>
#include <string.h>
size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream)
{
size_t written;
written = fwrite(ptr, size, nmemb, stream);
return written;
}
int main(void)
{
CURL *curl;
FILE *fp;
CURLcode res;
int x;
char y[200];
char page;
char outfilename[FILENAME_MAX];
char path_pdf = "/home/user_name/Desktop/document.pdf";
char path_jpg = "/home/user_name/Desktop/picture.jpg";
char path_txt = "/home/user_name/Desktop/document.txt";
char FILEPATH[2] = {path_pdf, path_jpg, path_txt};
printf("Enter file url \n"); // for example http://oi58.tinypic.com/15nk3de.jpg
scanf ("%s",y);
char *url = "y";
printf("Choose type of file:\n [0] - pdf\n [1] - jpg\n [2] - txt\n "); //choose 1
scanf("%d",x);
outfilename[FILENAME_MAX] = FILEPATH[x];
curl = curl_easy_init();
if (curl)
{
fp = fopen(outfilename,"wb");
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
curl_easy_setopt (curl, CURLOPT_VERBOSE, 1L);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
fclose(fp);
}
return 0;
}
There are several reasons that your code isn't working:
path_pdf, path_jpg, and path_txt should be type char*
FILEPATH should be declared as char FILEPATH[3] = {path_pdf, path_jpg, path_txt}; as RaptorDotCpp pointed out.
Your second scanf call should be scanf("%d", &x); since scanf requires the arguments after the format to be pointers. This is where your code segfaulted when I tested it.
url should be initialized as char *url = y;. This sets url to the value the user entered instead of only the letter "y".
outfilename[FILENAME_MAX] = FILEPATH[x]; writes past the end of outfilename. Use outfilename = FILEPATH[x]; instead, which won't cause a buffer overflow.
I am trying to convert a c++ program I have which uses random library which is a C++11 feature. After having read through a couple of similar posts here, I tried by separating out the code into three files. At the outset I would like to say that I am not very conversant at C/C++ and mostly use R at work.
The main file looks as follows.
#ifndef _KERNEL_SUPPORT_
#define _KERNEL_SUPPORT_
#include <complex>
#include <random>
#include <iostream>
#include "my_code_header.h"
using namespace std;
std::default_random_engine generator;
std::normal_distribution<double> distribution(0.0,1.0);
const int rand_mat_length = 24561;
double rand_mat[rand_mat_length];// = {0};
void create_std_norm(){
for(int i = 0 ; i < rand_mat_length ; i++)
::rand_mat[i] = distribution(generator);
}
.
.
.
int main(void)
{
...
...
call_global();
return 0;
}
#endif
The header file looks as follows.
#ifndef mykernel_h
#define mykernel_h
void call_global();
void two_d_example(double *a, double *b, double *my_result, size_t length, size_t width);
#endif
And the .cu file looks like the following.
#ifndef _MY_KERNEL_
#define _MY_KERNEL_
#include <iostream>
#include "my_code_header.h"
#define TILE_WIDTH 8
using namespace std;
__global__ void two_d_example(double *a, double *b, double *my_result, size_t length, size_t width)
{
unsigned int row = blockIdx.y*blockDim.y + threadIdx.y;
unsigned int col = blockIdx.x*blockDim.x + threadIdx.x;
if ((row>length) || (col>width)) {
return;
}
...
}
void call_global()
{
const size_t imageLength = 528;
const size_t imageWidth = 528;
const dim3 threadsPerBlock(TILE_WIDTH,TILE_WIDTH);
const dim3 numBlocks(((imageLength) / threadsPerBlock.x), ((imageWidth) / threadsPerBlock.y));
double *d_a, *d_b, *mys ;
...
cudaMalloc((void**)&d_a, sizeof(double) * imageLength);
cudaMalloc((void**)&d_b, sizeof(double) * imageWidth);
cudaMalloc((void**)&mys, sizeof(double) * imageLength * imageWidth);
two_d_example<<<numBlocks,threadsPerBlock>>>(d_a, d_b, mys, imageLength, imageWidth);
...
cudaFree(d_a);
cudaFree(d_b);
}
#endif
Please note that the __global__ has been removed from .h since I was getting the following error owing to it being compiled by g++.
In file included from my_code_main.cpp:12:0:
my_code_header.h:5:1: error: ‘__global__’ does not name a type
When I compile the .cu file with nvcc it is all fine and generates a my_code_kernel.o. But since I am using C++11 in my .cpp I am trying to compile it with g++ and I am getting the following error.
/tmp/ccR2rXzf.o: In function `main':
my_code_main.cpp:(.text+0x1c4): undefined reference to `call_global()'
collect2: ld returned 1 exit status
I understand that this might not have to do anything with CUDA as such and may just be the wrong use of including the header at both places. Also what is the right way to compile and most importantly link the my_code_kernel.o and my_code_main.o(hopefully)? Sorry if this question is too trivial!
It looks like you are not linking with my_code_kernel.o. You have used -c for your nvcc command (causes it to compile but not link, i.e. generate the .o file), I'm going to guess that you're not using -c with your g++ command, in which case you need to add my_code_kernel.o to the list of inputs as well as the .cpp file.
The separation you are trying to achieve is completely possible, it just looks like your not linking properly. If you still have problems, add the compilation commands to your question.
FYI: You don't need to declare two_d_example() in your header file, it is only used within your .cu file (from call_global()).
I'm trying to read the memory of a process using task_for_pid / vm_read.
uint32_t sz;
pointer_t buf;
task_t task;
pid_t pid = 9484;
kern_return_t error = task_for_pid(current_task(), pid, &task);
vm_read(task, 0x10e448000, 2048, &buf, &sz);
In this case I read the first 2048 bytes.
This works when I know the base address of the process (which I can find out using gdb "info shared" - in this case 0x10e448000), but how do I find out the base address at runtime (without looking at it with gdb)?
Answering my own question. I was able to get the base address using mach_vm_region_recurse like below. The offset lands in vmoffset. If there is another way that is more "right" - don't hesitate to comment!
#include <stdio.h>
#include <mach/mach_init.h>
#include <sys/sysctl.h>
#include <mach/mach_vm.h>
...
mach_port_name_t task;
vm_map_offset_t vmoffset;
vm_map_size_t vmsize;
uint32_t nesting_depth = 0;
struct vm_region_submap_info_64 vbr;
mach_msg_type_number_t vbrcount = 16;
kern_return_t kr;
if ((kr = mach_vm_region_recurse(task, &vmoffset, &vmsize,
&nesting_depth,
(vm_region_recurse_info_t)&vbr,
&vbrcount)) != KERN_SUCCESS)
{
printf("FAIL");
}
Since you're calling current_task(), I assume you're aiming at your own process at runtime. So the base address you mentioned should be the dynamic base address, i.e. static base address + image slide caused by ASLR, right? Based on this assumption, you can use "Section and Segment Accessors" to get the static base address of your process, and then use the dyld functions to get the image slide. Here's a snippet:
#import <Foundation/Foundation.h>
#include </usr/include/mach-o/getsect.h>
#include <stdio.h>
#include </usr/include/mach-o/dyld.h>
#include <string.h>
uint64_t StaticBaseAddress(void)
{
const struct segment_command_64* command = getsegbyname("__TEXT");
uint64_t addr = command->vmaddr;
return addr;
}
intptr_t ImageSlide(void)
{
char path[1024];
uint32_t size = sizeof(path);
if (_NSGetExecutablePath(path, &size) != 0) return -1;
for (uint32_t i = 0; i < _dyld_image_count(); i++)
{
if (strcmp(_dyld_get_image_name(i), path) == 0)
return _dyld_get_image_vmaddr_slide(i);
}
return 0;
}
uint64_t DynamicBaseAddress(void)
{
return StaticBaseAddress() + ImageSlide();
}
int main (int argc, const char *argv[])
{
printf("dynamic base address (%0llx) = static base address (%0llx) + image slide (%0lx)\n", DynamicBaseAddress(), StaticBaseAddress(), ImageSlide());
while (1) {}; // you can attach to this process via gdb/lldb to view the base address now :)
return 0;
}
Hope it helps!