#include <Windows.h>
void memfrob(void * s, size_t n)
{
char *p = (char *) s;
while (n-- > 0)
*p++ ^= 42;
}
int main()
{
memfrob("C:\\Program Files\\***\***\\***\***\\***", 30344);
}
There's my code. If you can't tell, I'm not sure what I'm doing. I've Googled for about an hour and I haven't seen an example of how to use memfrob(), which is probably why I'm so lost. I'm trying to pass it the name of the file and then the size of the file in bytes, but my program just crashes.
Alright, this is what I have right now:
#include <Windows.h>
#include <stdio.h>
int count = 0;
FILE* pFile = 0;
long Size = 0;
void *memfrob(void * s, size_t n)
{
char *p = (char *) s;
while (n-- > 0)
*p++ ^= 42;
return s;
}
int main()
{
fopen_s(&pFile, "C:\\Program Files\\CCP\\EVE\\lib\\corelib\\nasty.pyj", "r+");
fseek(pFile, 0, SEEK_END);
Size = ftell(pFile);
char *buffer = (char*)malloc(Size);
memset(buffer, 0, Size);
fread(buffer, Size, 1, pFile);
fclose(pFile);
memfrob(buffer, Size);
fopen_s(&pFile, "C:\\Program Files\\CCP\\EVE\\lib\\corelib\\nasty.pyj", "w+");
fwrite(buffer, Size, 1, pFile);
fclose(pFile);
}
In my debugger, it seems that fread is not writing anything to buffer, and my ending file is just 2A over and over, which is 00 xor'd with 42. So can I get another hint?
You need to pass memfrob a piece of memory containing the contents of the file, rather than the name of the file. It's crashing because you're passing in a buffer of read-only memory, and then trying to modify it.
Investigate the open and read I/O functions, or alternatively fopen and fread. Your mainline should look something like:
int main() {
// open file
// find size of file
// allocate buffer of that size
// read contents of file into the buffer
// close the file
// call memfrob on the buffer
// do what you want with the file
// free the buffer
}
Well, several things are wrong here.
The minor problem is that you're passing it the location of the file and not the file itself. Read up on how to do file I/O in C (this being a pretty good link).
The real problem is that you seem to think this is encryption. This doesn't really encrypt your file from anything but the most trivial security issues (such as someone randomly opening your file).
Related
I have 2 programs communicating with each other through a fifo, one's the writer the other's the reader.
The writer sends a pointer to a struct containing information.
The reader should receive the pointer and be able to see the information inside the struct.
Header file:
typedef struct req{
int _code;
char _client_pipe[PIPENAME];
char _box_name[BOXNAME];
} request;
/*writes to pipe tx a pointer with information*/
void send_request(int tx, request *r1) {
ssize_t ret = write(tx, &r1, sizeof(r1));
if (ret < 0) {
fprintf(stdout, "ERROR: %s\n", ERROR_WRITING_PIPE);
exit(EXIT_FAILURE);
}
}
/*Returns a pointer to a struct containing the request*/
request *serialize(int code, char* client_pipe, char* box_name){
request *r1 = (request*) malloc(sizeof(request));
r1->_code = code;
strcpy(r1->_client_pipe, client_pipe);
strcpy(r1->_box_name, box_name);
return r1;
}
Program writer:
int main(int argc, char **argv){
(void *) argc; // in my program i used argc, but for this problem it's not important hence why the //typecast to void
char register_pipe[PIPENAME];
char personal_pipe[PIPENAME];
char box_name[BOXNAME];
strcpy(register_pipe, argv[1]);
strcpy(personal_pipe, argv[2]);
strcpy(box_name, argv[3]);
int reg_pipe = open(register_pipe, O_WRONLY);
if (reg_pipe == -1) {
fprintf(stdout, "ERROR: %s\n", UNEXISTENT_PIPE);
return -1;
}
send_request(reg_pipe, serialize(1, personal_pipe, box_name));
}
Program reader:
char register_pipe[PIPENAME];
strcpy(register_pipe, argv[1]);
if(mkfifo(register_pipe, 0644) < 0)
exit(EXIT_FAILURE);
if ((reg_pipe = open(register_pipe, O_RDONLY)) < 0){
exit(EXIT_FAILURE);
}
if ((reg_pipe = open(register_pipe, O_RDONLY)) < 0){
exit(EXIT_FAILURE);
}
request* buffer = (request*) malloc(sizeof(request)); //this might be the issue but not sure
ssize_t broker_read= read(reg_pipe, buffer, 256); //is not reading correctly
printf("%d, %s, %s\n", buffer->_code, buffer->_client_pipe, buffer->_box_name);
So if i start program reader and set register pipe as "reg", this will create the register pipe and wait for someone to join it.
Then if i start the program writer like ./writer reg personal box
this will open the reg pipe correctly, create a struct of type request and then sent it to the reader.
The reader should receive a pointer to a struct req set like:
_code = 1;
_client_pipe[PIPENAME] = "personal";
_box_name[BOXNAME] = "box";
The reader is in fact receiving but for some reason it's not receiving correctly.
If i try to print like in the last line, it will output some random numbers and letters.
How can i fix this?
You would need to have that structure exist inside a shared memory region that you have arranged to be mapped into both processes at the same address.
Without some such arrangement, each process has a private address space, so an address known to process A is meaningless to process B.
How to make such an arrangement is very much dependent upon you operating system, and perhaps even variant of said operating system.
You will likely find it easier to just copy the structure, as opposed to its address, via the fifo.
According to the manual page of the truncate function in R, on some platforms including Windows:
... it will not work for large (> 2Gb) files
After some experimentation, I managed to make up a toy example showing that it is possible to do this for large files (quite easily) with visual c++:
// ConsoleApplication1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#include <tlhelp32.h>
#include <tchar.h>
#include <iostream>
#include <string>
// Forward declarations:
void append(LPCTSTR, LPCVOID, DWORD);
void readTail(LPCTSTR, LPVOID, DWORD);
void truncateTail(LPCTSTR, long);
int main()
{
LPCTSTR fn = L"C:/kaiyin/kybig.out";
char buf[] = "helloWorld";
append(fn, buf, 10);
BYTE buf1[10] = {0};
readTail(fn, buf1, 5);
std::cout << (char*) buf1 << std::endl;
//truncateTail(fn, 5);
//for (int i = 0; i < 10; i++) {
// buf1[i] = 0;
//}
//readTail(fn, buf1, 5);
//std::cout << (char*) buf1 << std::endl;
printf("End of program\n");
std::string s = "";
std::getline(std::cin, s);
return 0;
}
void append(LPCTSTR filename, LPCVOID buf, DWORD writeSize) {
LARGE_INTEGER size;
size.QuadPart = 0;
HANDLE fh = CreateFile(filename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
GetFileSizeEx(fh, &size);
SetFilePointerEx(fh, size, NULL, FILE_BEGIN);
WriteFile(fh, buf, writeSize, NULL, NULL);
CloseHandle(fh);
}
void readTail(LPCTSTR filename, LPVOID buf, DWORD readSize) {
LARGE_INTEGER size;
size.QuadPart = 0;
HANDLE fh = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
GetFileSizeEx(fh, &size);
size.QuadPart -= readSize;
SetFilePointerEx(fh, size, NULL, FILE_BEGIN);
ReadFile(fh, buf, readSize, NULL, NULL);
CloseHandle(fh);
}
void truncateTail(LPCTSTR filename, long truncateSize) {
LARGE_INTEGER size;
size.QuadPart = 0;
HANDLE fh = CreateFile(filename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (fh == INVALID_HANDLE_VALUE) {
std::cerr << GetLastError();
return;
}
GetFileSizeEx(fh, &size);
size.QuadPart -= truncateSize;
SetFilePointerEx(fh, size, NULL, FILE_BEGIN);
if (SetEndOfFile(fh) == 0) {
std::cerr << GetLastError();
return;
}
CloseHandle(fh);
}
This will append "helloWorld" to the file "C:/kaiyin/kybig.out", and then truncate "World". In the console it should print "World" (tail before truncating), then "hello" (tail after truncating).
There seems to be no problem at all in truncating the tail of a file larger than 2GB -- in fact, I have tested with a 4e9 byte file and the program still behaves correctly.
Am I missing something, or is it true that the truncate function can indeed be reliably (and easily) implemented on Windows?
Update
Following #hrbrmstr's reference to this R bugzilla link, I tried some R code to verify whether the truncate function works properly on Windows 8.1:
filename = "C:/kaiyin/kybig.out"
f = file(filename, "w")
seek(f, 5L, "end")
truncate(f)
file.info(filename)$size
Results:
> filename = "C:/kaiyin/kybig.out"
> f = file(filename, "w")
> seek(f, 5L, "end")
[1] 0
> truncate(f)
NULL
> file.info(filename)$size
[1] 0
Apparently truncate just trashes everything despite the seeking to near the end.
Am I missing something, or is it true that the truncate function can indeed be reliably (and easily) implemented on Windows?
The likely explanation is that the problem is nothing to do with Windows but all to do with the implementation of the R function. On Windows it likely uses a signed 32 bit integer to specify the truncated file size, hence the limitation.
It's also plausible that the documentation could be out of date, and that the R developers have now managed to work out how to implement this function correctly on Windows.
R does not seem to use the Windows API to access files, instead it looks like it uses a POSIX (or POSIX-like) layer, at least according to the source code I mentioned in the linked question. So, while truncating huge files probably works on Windows using the Windows API (as shown in your code), it may well be that this POSIX(-like) layer that R uses does not (yet) fully support this (again, see source).
I am writing a data logger and would like to keep the files limited to a specific number of entries. I am trying to write this bit of code in the setup, so that when the Arduino powers on, it will write to a new file just to keep things simple. However, when I try to open the file I can't, although I am not sure why. Can anyone offer any explanation?
char *fileName; //global name
File logFile; //global file
//everything else is in setup()
char * topPart = "/Data/Data"; //first part of every file
char * lowerPart = ".txt"; // jus the extention
char * itter; //used to hold the char of i later
fileName = "/Data/Data.txt"; //start with the first file possible.
for(int i=0; i<=100;i++) {
if(!SD.exists(fileName)) {
Serial.print("opening file: ");
Serial.print(fileName);
logFile = SD.open(fileName, FILE_WRITE);
if(logFile) {
logFile.println("I made it");
Serial.println("in the file");
}
if(!logFile) {
Serial.println("somthing bad");
}
break;
} else {
itter = (char *)(i+48);
strcpy(fileName,topPart);
strcpy(fileName,itter);
strcpy(fileName,lowerPart);
Serial.println(i);
}
}
Lots of problems.
the construction of itter is wrong.
strcpy doesn't append just cpy.
Here is a code example to build your filename. This a basic C program. Remove the #include and main for Arduino, this allows to test on your computer whether the program is ok.
#include <string.h>
#define TOPPART "/Data/Data"
#define LOWERPART ".txt"
int main(void) {
char buf[64];
snprintf(buf, sizeof(buf), "%s%s", TOPPART, LOWERPART);
for (int i = 0; i < 100; i++) {
/* here your stuff to check if the filename froml buf exists*/
snprintf(buf, sizeof(buf), "%s%d%s", TOPPART, i, LOWERPART);
}
return 0;
}
I am trying to get interact with the internal memory of the PIC24F16KA101 MCU. After reading the data-sheet and the discussion on this site (which offer a pretty helpful sample code)used in the project
Now if I put the code below the program work just fine, since I am able to read successfully the same value that I wrote previously. However if after writing I unplug the MCU and perform only a read of the EEPROOM it is not going to return the value written. What could be the problem here?. Why can I write and then read successfully but can not read after a power off?.
Thanks in advance to all for the help
Damian
int __attribute__ ((space(eedata))) ee_addr;
void EepSetup();
void EepErase(void);
int EepWrite(int index, int data);
int EepRead(int index);
int main(int argc, char** argv)
{
unsigned int data = 123;
unsigned int data_read = 0;
Init_UART1();
UART1WriteString("START EEPROM PROGRAM \n");
EepSetup();
UART1WriteString("WRITING DATA TO MEMORY \n");
EepWrite(1,data);
//if the code works, just comment the upper section and read eeprom after
//disconecting the power source
UART1WriteString("READING DATA FROM MEMORY \n");
data_read = EepRead(1);
UART1WriteString("Value Read: ");
UART1WriteInt(data_read,16);
UART1WriteString("\n");
__delay_ms(1000);
return (EXIT_SUCCESS);
}
void EepSetup(){
//Disable Interrupts For 5 instructions
asm volatile("disi #5");
//Issue Unlock Sequence
asm volatile("mov #0x55, W0 \n"
"mov W0, NVMKEY \n"
"mov #0xAA, W1 \n"
"mov W1, NVMKEY \n");
}
void EepErase(void) {
NVMCON = 0x4050; // Set up NVMCON to bulk erase the data EEPROM
asm volatile ("disi #5"); // Disable Interrupts For 5 Instructions
__builtin_write_NVM(); // Issue Unlock Sequence and Start Erase Cycle
while(_WR)
;
}
int EepRead(int index){
unsigned int offset;
TBLPAG = __builtin_tblpage(&ee_addr); // Initialize EE Data page pointer
offset = __builtin_tbloffset(&ee_addr); // Initizlize lower word of address
offset += index * sizeof(int);
return __builtin_tblrdl(offset); // read EEPROM data
}
int EepWrite(int index, int data){
unsigned int offset;
NVMCON = 0x4004; // Set up NVMCON to erase one word of data EEPROM
TBLPAG = __builtin_tblpage(&ee_addr); // Initialize EE Data page pointer
offset = __builtin_tbloffset(&ee_addr); // Initizlize lower word of address
offset += index * sizeof(int);
__builtin_tblwtl(offset, data);
asm volatile ("disi #5"); // Disable Interrupts For 5 Instructions
__builtin_write_NVM(); // Issue Unlock Sequence and Start Erase Cycle
while(_WR);
return (EXIT_SUCCESS);
}
I just figured out what the problem was, it happens that if you use the PICkit 3 with MPLABX you have to check an option in the programmer to preserve the EEPROM memory,so the code was functional, you just need to check the option of "Preserve EEPROM Memory" in the programmer settings. I hope this help others.
Cheers, Damian
so i know the bases of programming, i have a decent amount of experience with java, but im learning C for school right now. I still dont completely understand the whole pointer aspect, which is what im sure caused the fault. This program works fine when run on my computer, but when i try and run it on my schools unix shell it gives me a seg fault. if someone could please explain to me why or how ive misused hte pointers, that would help me greatly.
//Matthew Gerton
//CS 222 - 002
//10/10/14
//HW Six
//libraries
#include<stdio.h>
#include<string.h>
#define max_Length 256
//prototypes
void decode(char *a, char *b);
void trimWhite(char *a);
void encode(char *a, char *b);
int main(void)
{
//character arrays
char coded[max_Length], decoded[max_Length];
//decode the sample phrase
char sample[] = {'P','H','H','W','D','W','C','R','R','F','D','Q','F','H','O','H','G','J',
'R','W','R','P','H','W','U','R','K','R','W','H','O','U','R','R','P','I','R','X','U'};
decode(sample, decoded);
//scans a user input string to decode, and decodes it
printf("\nPlease enter a phrase to decode: ");
gets(coded);
trimWhite(coded);
decode(coded, decoded);
//scans a user input phrase to encode
printf("\nPlease enter a phrase to encode: ");
gets(coded);
trimWhite(coded);
encode(coded, decoded);
}
//removes any spaces from the input
void trimWhite(char *a)
{
char temp[max_Length];
int z=0, y=0;
while(a[z]!='\0')
{
if(a[z]!=' ')
{
temp[y]=a[z];
y++;
}
z++;
}
temp[y] = '\0';
strcpy(a,temp);
}
//decodes any phrase
void decode(char *a, char *b)
{
int i=0,n;
memset(b, '\0', sizeof(b));
while(a[i]!='\0')
{
n=(int)a[i];
if(n<97)
n=n+32;
if(n<=99)
n=n+23;
else
n = n-3;
b[i]= (char) n;
i++;
}
b[i]='\0';
printf("Coded message: %s\n", a);
printf("Decoded message: %s\n", b);
}
//codes an input phrase
void encode(char *a, char *b)
{
int i=0,n;
memset(b, '\0', sizeof(b));
strcpy(b,a);
while(a[i]!='\0')
{
n=(int)a[i];
if(n<97)
a[i] = (char)(n+32);
if((n>120)
a[i] = (char)(n-23);
else
a[i] = (char)((n+3);
i++;
}
printf("Coded message: %s\n", a);
}
Your main problem is here:
char sample[] = {'P','H','H', /* snip */ ,'R','X','U'};
The sample[] array is not zero-terminated which may cause the decode() function to copy many more characters than intended, thus overwriting other variables. You need to explicitly add a terminating zero when using an initializer-list:
char sample[] = {'P','H','H', /* ... */ ,'R','X','U',0};
Or you can initialize the array using a string literal, which does include a terminating zero:
char sample[] = "PHHWDWCRRFDQFHOHGJRWRPHWURKRWHOURRPIRXU";
You should probably read "Why is the gets function dangerous".
...
void decode(char *a, char *b)
{
int i=0,n;
memset(b, '\0', sizeof(b));
Also note that the size of the array is lost when it is passed to a function. The function only receives a pointer to its first element. The memset() call above will only zero sizeof(char*) bytes (usually 4 or 8). This doesn't matter though because, as far as I can tell, you only need to zero the first byte. You could simply write:
b[0] = 0;