PE FILE reading in c - c

I need to check if file is PE file or not. I need to check first two byte is MZ or not and I did this.
This is my task: When verifying the PE format, not only according to the MZ expression, but also using the conditions that the IMAGE_NT_HEADERS structure is read and the Signature field is verified by reading the IMAGE_FILE_HEADER field and the Machine field is equal to the Th value IMAGE_FILE_MACHINE_I386 or IMAGE_FILE_MACHINE_AMD64.
I cannot figure how can do the rest of them. I hope you can help me.
int checkPE(char *file){
int fd=open(file,READ_FLAGS,0777);
char buffer[TWOBYTE+1] = {'\0'};
size_t bytes_read;
char ch;
if(fd==-1){ //if file cannot be opened give a error message.
perror("The file cannot be opened.\n");
return -1;
}
bytes_read = read(fd,buffer,TWOBYTE);
if(bytes_read==-1){
perror("Error while reading file\n");
return -1;
}
if(strcmp(buffer,MZ)!=0){
return -1;
}
int closeFlag = close(fd);
if(closeFlag==-1){
perror("The file cannot be closed.\n");
return -1;
}
}

There is nothing more than just parsing some structures. You have already the algorithm. I assume that you just need the implementation. Consider the following example utility.
PS: For further details, just comment it below.
#include <stdio.h>
#include <windows.h>
BOOL CheckValidity(BYTE* baseAddress);
int main(int argc, char* argv[]) {
if (argc != 2)
{
printf("You didn't specified a PE file.\n");
printf("Usage: CheckPEImage.exe <Full path of PE File>\n");
return -1;
}
HANDLE hFile = CreateFileA(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return -1;
HANDLE hMemoryMap = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if (!hMemoryMap)
return -2;
PBYTE baseAddress = (PBYTE)MapViewOfFile(hMemoryMap, FILE_MAP_READ, 0, 0, 0);
if (!baseAddress)
return -3;
printf("PE Image is %s.\n", CheckValidity(baseAddress) ? "valid" : "invalid");
getchar();
return 0;
}
BOOL CheckValidity(BYTE* baseAddress)
{
PIMAGE_DOS_HEADER lpDosHeader;
PIMAGE_FILE_HEADER lpFileHeader;
PIMAGE_NT_HEADERS lpNtHeaders;
PIMAGE_OPTIONAL_HEADER lpOptionalHeader;
lpDosHeader = (PIMAGE_DOS_HEADER)baseAddress;
lpNtHeaders = (PIMAGE_NT_HEADERS)(baseAddress + lpDosHeader->e_lfanew);
if (lpDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
return FALSE;
if (lpNtHeaders->Signature != IMAGE_NT_SIGNATURE)
return FALSE;
if (lpNtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_I386 && lpNtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64)
return FALSE;
return TRUE;
}

Related

Set files.txt into program's arguments in code blocks

My question is simple, I am a beginner in c language, I am currently developing the hangman game on code blocks. To do this a restriction was imposed on me, the file in which my word dictionary is located, I must pass it as an argument in my program. I saw in my research that in the project -> Set program's arguments .. tab, we can add arguments, but I cannot pass my text file as a parameter. Anyone have a solution please? thank you so much
I pass it like this :
But when I build my program it does not detect my file.
this is the code that tries to read the file
char *read_file(int ac, char **av, int *lifes, char **word)
{
int fd = -1;
int nb_caractere = 0;
char *buffer = calloc(1,sizeof(char));
if((fd = open(av[1], O_RDONLY)) == -1)
{
printf("Aucun fichier ou dossier. \n");
return (NULL);
}
lseek(fd, 0, SEEK_SET);
while(read(fd, buffer, 1) > 0)
{
nb_caractere++;
}
lseek(fd, 0, SEEK_SET);
buffer = calloc(nb_caractere+1, sizeof(char));
memset(buffer, 0, nb_caractere+1);
read(fd, buffer, nb_caractere);
close(fd);
return (buffer);
}
and the main how call this funtion is this :
int main(int ac, char **av)
{
int lifes = 10;
char *word = NULL;
char *hide_word = NULL;
srand(time(NULL));
if(ac < 2 || ac > 3)
{
printf("Nombres d'arguments incorrect !\n");
return (84);
}
if(ac == 3)
{
lifes = atoi(av[2]);
}
if(init_game(lifes, &word, &hide_word, read_file(ac, av, &lifes,
&word)) == 84 )
{
free(word);
return (84);
}
game_loop(lifes, word, hide_word);
free(word);
free(hide_word);
return 0;
}
the output of this code is "aucun fichier ou dossier"

WIndow CreateFile ReadFile WriteFile

I am a student so I apologize up front for not using the correct forum protocols. I am new to C, and really new to Win32 API. My assignment is to write a small C program that copies the contents of an existing file to a new file, using only Win32 I/O system calls: CreateFile(), ReadFile(), WriteFile(), etc... File names are to be specified on the command line. Right now I'm just trying to get the basics functions in place, I will then focus on error handling. This code compiles, creates a new file, but the data does not get copied to it. Any advice? thanks for taking a look!
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
int main(int argc, char *argv[])
{
char buff[4096];
DWORD dwBytesRead, dwBytesWritten;
DWORD dwBytesToWrite = (DWORD)strlen(buff);
//open source file and read it
HANDLE source;
// Create a handle for the source file
source=CreateFile(argv[1], GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
// Check for errors
if ( source == INVALID_HANDLE_VALUE ){
printf("Error, source file not opened.");
exit(EXIT_FAILURE);
}
else printf("The source file is %s\n", argv[1]);
//create a new file
HANDLE target;
target = CreateFile(argv[2], GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if ( target == INVALID_HANDLE_VALUE ){
printf("Error, target file not created.");
exit(EXIT_FAILURE);
}
else printf("The source file is %s\n", argv[2]);
//copy contents
ReadFile(source, buff, 4096, &dwBytesRead, NULL);
WriteFile(target, buff, dwBytesToWrite, &dwBytesWritten, NULL);
//copy complete
CloseHandle(source);
CloseHandle(target);
return 0;
}
As mentioned in comments, your code has a few mistakes in it. Try something more like this instead:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
int main(int argc, char *argv[])
{
char buff[4096];
DWORD dwBytesRead, dwBytesWritten;
// Open the source file
HANDLE source = CreateFileA(argv[1], GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
// Check for error
if (source == INVALID_HANDLE_VALUE) {
printf("Source file not opened. Error %u", GetLastError());
return EXIT_FAILURE;
}
printf("The source file is %s\n", argv[1]);
// Create a new file
HANDLE target = CreateFileA(argv[2], GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
// Check for error
if (target == INVALID_HANDLE_VALUE) {
printf("Target file not created. Error %u", GetLastError());
CloseHandle(source);
return EXIT_FAILURE;
}
printf("The target file is %s\n", argv[2]);
// Copy contents
bool ok = true;
do {
// Read file, check for error
if (!ReadFile(source, buff, sizeof(buff), &dwBytesRead, NULL)) {
printf("Source file not read from. Error %u", GetLastError());
ok = false;
break;
}
// Check for EOF reached
if (dwBytesRead == 0) {
break;
}
// Write file, check for error
if (!WriteFile(target, buff, dwBytesRead, &dwBytesWritten, NULL)) {
printf("Target file not written to. Error %u", GetLastError());
ok = false;
break;
}
}
while (true);
// Copy complete
CloseHandle(source);
CloseHandle(target);
// Check for error
if (!ok) {
DeleteFileA(argv[2]);
return EXIT_FAILURE;
}
// all OK
return 0;
}

What does it mean for ReadFile to be "completing asynchronously", and why is it an error?

I'm (synchronously) reading serial input in Windows using ReadFile(), but instead of waiting for the serial port to have input then returning that as I thought it should, ReadFile() instead returns immediately with a value of FALSE, and a GetLastError() of 0. (Yes, I'm certain I have the right error code and am not making syscalls in between).
The ReadFile() documentation says that when the function "is completing asynchronously, the return value is zero (FALSE)." How is it that a synchronous read can be completing asychronously? Why would this be an error? It's worth noting that the data read is garbage data, as one might expect.
More generally, how can I force ReadFile() to behave like a simple synchronous read of a serial port, or at least behave something like the UNIX read()?
Edit: Here is some source code:
HANDLE my_connect(char *port_name)
{
DCB dcb;
COMMTIMEOUTS timeouts;
HANDLE hdl = CreateFile(port_name,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
GetCommState(port_name, &dcb);
dcb.BaudRate = 115200;
dcb.ByteSize = 8;
dcb.StopBits = ONESTOPBIT;
dcb.Parity = NOPARITY;
if(SetCommState(hdl, &dcb) == 0)
{
fprintf(stderr, "SetCommState failed with error code %d.\n",
GetLastError());
return (HANDLE) -1;
}
/* TODO: Set a variable timeout. */
timeouts.ReadIntervalTimeout = 0;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.ReadTotalTimeoutConstant = 5000; /* wait 5s for input */
timeouts.WriteTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 5000;
if(SetCommTimeouts(hdl, &timeouts) == 0)
{
fprintf(stderr, "SetCommTimeouts failed with error code %d.\n",
GetLastError());
return (HANDLE) -1;
}
return hdl;
}
int my_disconnect(HANDLE hdl)
{
return CloseHandle(hdl);
}
int my_send(HANDLE hdl, char *cmd)
{
DWORD nb = 0;
if(WriteFile(hdl, cmd, strlen(cmd), &nb, NULL) == 0)
{
fprintf(stderr, "WriteFile failed with error code %d.\n",
GetLastError());
return -1;
}
return (int) nb;
}
int my_receive(HANDLE hdl, char *dst, int dstlen)
{
int i;
DWORD r;
BOOL err;
char c = '\0';
for (i = 0; i < dstlen; err = ReadFile(hdl, &c, 1, &r, NULL))
{
if (err == 0)
{
fprintf(stderr, "ReadFile failed with error code %d.\n",
GetLastError());
return -1;
}
if (r > 0)
{
dst[i++] = c;
if (c == '\n') break;
}
}
if (i == dstlen)
{
fprintf(stderr, "Error: read destination buffer not large enough.\
Recommended size: 256B. Your size: %dB.\n", dstlen);
return -1;
}
else
{
dst[i] = '\0'; /* null-terminate the string. */
}
return i;
}
And my test code:
HANDLE hdl = my_connect("COM4");
char *cmd = "/home\n"; /* basic command */
char reply[256];
my_send(hdl, cmd);
my_receive(hdl, reply, 256);
puts(reply);
It's not completing asynchronously. If it were, GetLastError would return ERROR_IO_PENDING.
To do synchronous I/O, open the file without FILE_FLAG_OVERLAPPED.
It should not be possible for ReadFile to fail without a valid GetLastError code. ReadFile only returns false when the driver sets a non-success status code.

Checking Linux kernel config at runtime

Is there any C function that can check whether a Linux kernel configuration option (CONFIG_AAAA option in /boot/config- file) is set?
Or I have to develop it myself.
After a long search with no result, I developed a function myself. Here is the code:
static int is_kconfig_set(const char *config) {
int ret = 0;
struct utsname utsname;
char pattern[BUFSIZ], buf[BUFSIZ];
FILE *fp = NULL;
if (uname(&utsname) == -1)
return 0;
memset(pattern, 0, sizeof(pattern));
memset(buf, 0, sizeof(buf));
sprintf(pattern, "%s=y", config);
sprintf(buf, "/boot/config-%s", utsname.release);
fp = fopen(buf, "r");
if (fp == NULL)
return 0;
while(fgets(buf, sizeof(buf), fp) != NULL) {
if (strncmp(buf, pattern, strlen(pattern)) == 0) {
ret = 1;
break;
}
}
fclose(fp);
return ret;
}
To check whether CONFIG_CPU_FREQ is set:
if (is_kconfig_set("CONFIG_CPU_FREQ"))
return 1;
return 0;
The only way I can think is to create your own following the approach in kernel/configs.c (this is the code that creates /proc/config.gz).

libs3 S3StatusConnectionFailed

I'm working on doing file uploads using the libs3 library found here: http://libs3.ischo.com/dox/index.html
I'm getting back an error of S3StatusConnectionFailed though. Can someone point me to how this situation could arise? This is my function for uploading files into S3.
int putFileIntoS3 (char *fileName, char *s3ObjName) {
S3Status status;
char *key;
struct stat statBuf;
uint64_t fileSize;
FILE *fd;
char *accessKeyId;
char *secretAccessKey;
put_object_callback_data data;
accessKeyId = S3_ACCESS_KEY;
secretAccessKey = S3_SECRET_ACCESS_KEY;
key = (char*) strchr(s3ObjName, '/');
if (key == NULL) {
printf("S3 Key not defined!!!!");
return (-1);
}
*key = '\0';
key++;
if (stat(fileName, &statBuf) == -1) {
printf("Unknown input file");
return(-1);
}
fileSize = statBuf.st_size;
fd = fopen(fileName, "r");
if (fd == NULL) {
printf("Unable to open input file");
return(-1);
}
data.infile = fd;
S3BucketContext bucketContext =
{s3ObjName, S3ProtocolHTTP, S3UriStylePath, accessKeyId, secretAccessKey}
S3PutObjectHandler putObjectHandler = {
{ &responsePropertiesCallback, &responseCompleteCallback },
&putObjectDataCallback
};
if ((status = S3_initialize("s3", S3_INIT_ALL)) != S3StatusOK) {
printf("Failed to initialize libs3: %s\n",S3_get_status_name(status));
return(-1);
}
S3_put_object(&bucketContext, key, fileSize, NULL, 0, &putObjectHandler, &data);
if (statusG != S3StatusOK) {
printf("Put failed: %i\n", statusG);
S3_deinitialize();
return(-1);
}
S3_deinitialize();
fclose(fd);
return(0);
}
I get back "Put failed: 46", which I'm pretty sure means that it's an S3StatusConnectionFailed error.
Any help would be great, or even pointers to a boto-like library that I can use instead of the drudgery that is doing this in C++.
Thanks!
Ok, i tried putting non-null value but i was getting same error. i found out the reason for this : you must set the contentLength of "data" (of type put_object_callback_data) as below
fileSize = statBuf.st_size;
//viren+
data.contentLength = fileSize;
//viren-
//..
data.infile = fd;
Oh, and also make sure you have correct permissions set on your bucket.
use NULL for first param in S3_initialize. S3StatusConnectionFailed is indicative that "s3" url maybe wrong. i assume you are providing correct S3_ACCESS_KEY and S3_SECRET_ACCESS_KEY.

Resources