I am using a program written in Python which accepts an input from user though socket (I an not providing the code here in order not to confuse, since it runs fine with passing a String like: Hello world). Though what i want is to pass a big String through socket using python like:
$(python -c 'print "A" * 8000')
and the server to read 8000 times the letter 'A' not the above String as input. How is this possible?
EDIT:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define KEYFILESIZE 41
#define BUFF_SIZE 0X1000
#define PORTNO 12345
void firstFunc(int FD){
char buf[BUFF_SIZE];
int cookie=*(int*)(buf+0x1000);
printf("cookie: %x\n",cookie); //the server operator gets this info
read(FD,buf,BUFF_SIZE*2); //overflow the buffer 2x
return;
}
int servlet(int fd){
char greetings[BUFF_SIZE];
sprintf(greetings,"Greetings client #%d\n",fd);
write(fd,greetings,strlen(greetings));
firstFunc(fd);
char* sorry="Sorry";
write(fd,sorry,strlen(sorry));
return 0;
}
int main(int argc, char *argv[])
{
//char buffer[BUFFER_SIZE];
int sockfd, newsockfd, portno, pid;
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
/* if (argc < 2) { */
/* fprintf(stderr,"ERROR, no port provided\n"); */
/* exit(1); */
/* } */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0){
perror("ERROR opening socket");
exit(1);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
// portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(PORTNO);
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0){
perror("ERROR on binding");
exit(1);
}
listen(sockfd,5);
clilen = sizeof(cli_addr);
while (1) {
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0){
perror("ERROR on accept");
exit(1);
}
pid = fork();
if (pid < 0){
perror("ERROR on fork");
exit(1);
}
if (pid == 0) {
close(sockfd);
servlet(newsockfd);
exit(0);
}
//make sure to wait at some point to avoid zombies
else close(newsockfd);
waitpid(-1, NULL, WNOHANG);
}
close(sockfd);
return 0;
}
Ok so the above is the code of the server running in an Ubuntu vm. With netcat i connect to the server from another vm (running Kali) and i have tried to send as input:
1. $(python -c 'print "A" * 8000')
(python -c 'print "A" * 8000')
3.python -c 'print "A" * 8000'
None of the above worked. Below is a picture of what the server sees after each of the above
enter image description here
Of course what i wanted it to see in each case is 8000 'A' (AAAAAAAAAAAA....)
The answer to the question is to write a file in python which after the connection has been established (that is the part which i have done manually above with netcat ) will print the number of 'A' or any any string required. Example:
import socket
from struct import pack
host='ip_to_connect_to'
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port_to_connect_to))
answer=s.recv(1024)
print answer
padding=800 * "A"
s.send(padding)
Related
I was trying to figure out how the Mach VM Api works as there is almost 0 documentation around it and to do that I was messing around with reading/writing to other processes' memory.
To start I basically created a c program that constantly printed a string and its address. Then I used this program to try modifying the string mid execution and it worked fine:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <libproc.h>
#include <mach/mach.h>
#include <mach/mach_vm.h>
#define EXIT_ON_MACH_ERROR(msg, retval) \
if (kr != KERN_SUCCESS) { mach_error(msg ":" , kr); exit((retval)); }
uint32_t* get_pids(uint16_t* size) {
// Gets all PIDS on the system to locate specific PID later. Probably inefficient
// but I don't care
uint32_t number_of_pids = proc_listpids(1, 0, NULL, 0);
uint32_t* buffer = malloc(sizeof(uint32_t) * number_of_pids);
uint8_t return_code = proc_listpids(1, 0, buffer, sizeof(buffer) * number_of_pids);
uint16_t sum = 0;
for(int i = 0; i < number_of_pids; i++) {
if(buffer[i] != 0) {
sum++;
}
}
uint32_t* final = malloc(sizeof(uint32_t) * sum);
for(int i = 0, t = 0; i < number_of_pids; i++) {
if(buffer[i]) {
final[t++] = buffer[i];
}
}
*size = sum;
return final;
}
int main() {
// Locate correct PID according to process name
uint16_t size;
uint32_t* pids = get_pids(&size);
uint16_t maxpathlength = 1024;
uint16_t path_size = maxpathlength * 4;
char path_buffer[path_size];
uint32_t process_pid = 0;
for(int i = 0; i < size; i++) {
memset(path_buffer, '\0', sizeof(path_buffer));
uint8_t return_code = proc_pidpath(pids[i], path_buffer, path_size);
if(strstr(path_buffer, "Python")) {
printf("%d\n", i);
process_pid = pids[i];
}
//printf("PID: %d, Process: %s\n", pids[i], path_buffer);
}
printf("%d\n", process_pid);
struct proc_taskallinfo pro_info;
uint32_t status = proc_pidinfo(process_pid, PROC_PIDTASKALLINFO, 0, &pro_info, sizeof(pro_info));
printf("Python PID: %d\n", process_pid);
printf("Self PID: %d\n", mach_host_self());
mach_port_t port = 0;
kern_return_t kr = task_for_pid(mach_task_self(), process_pid, &port);
EXIT_ON_MACH_ERROR("task_for_pid", kr);
printf("Port: %d\n\n\n", port);
// STUFF
mach_vm_address_t address = 0x102d4b770;
mach_vm_address_t address_a = 0x102d4b770;
char data[50] = "wow";
vm_offset_t buf;
mach_msg_type_number_t sz;
// MEMORY DEALLOCATION
kern_return_t suc = mach_vm_deallocate(port, (mach_vm_address_t) address, (mach_vm_size_t) 1000);
if (suc!=KERN_SUCCESS)
{
printf("mach_vm_deallocate() failed with message %s!\n", mach_error_string(suc));
}
// MEMORY ALLOCATION
kern_return_t all_suc = mach_vm_allocate(port, (mach_vm_address_t *) &address_a, (vm_size_t) 26, false);
if (all_suc!=KERN_SUCCESS)
{
printf("mach_vm_allocate() failed with message %s!\n", mach_error_string(all_suc));
}
// WRITE TO MEMORY
kern_return_t success = mach_vm_write(port, (vm_address_t) address, (vm_address_t)data, 26);
if (success!=KERN_SUCCESS)
{
printf("mach_vm_write() failed with message %s!\n", mach_error_string(success));
}
// READ FROM MEMORY
kern_return_t read_success = mach_vm_read(port, (vm_address_t) 0x6000018c4030, 26, &buf, &sz);
if (read_success!=KERN_SUCCESS)
{
printf("mach_vm_read() failed with message %s!\n", mach_error_string(read_success));
}
char * newstr = (char *) buf;
printf("%s\n", newstr);
return 0;
}
address and address_a were entered manually after figuring out the variable's address. However, when I tried this with a python process where I again just constantly printed out the string and address, I got the following error message the instant I ran the code above:
zsh: segmentation fault python3 strtest.py
I have no knowledge about CPython, so even after playing around a bit and trying to make it work, nothing happened. How can I make this work even on programs? I know its possible as Bit-Slicer made it work but I wasn't able to found out how.
I am trying to have python connect to a tcp server written in C, the server and the client python script are running on the same machine (Linux). The C code compiles and runs without error. Yes they are using the same port of 27001. There can be no use of 3rd party libraries. Python says that the issue is on client.connect((HOST,PORT)), I get no read out from the C side of things. I've tried changing the ports, I know that these ports are unused as they are ports for many steam games, none of which are running while the server is online. I ran sudo netstat -ntlp in the terminal and I do not see my server, nor do I see the process id, or the port that I bound the server too.
Python:
import socket
def clientTest():
HOST=socket.gethostbyname("localhost")
print(HOST)
PORT=27001
client=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((HOST,PORT))
for i in range(5):
toSend="Data "
toSend+=str(i)
client.send(toSend)
print("Sent data")
time.sleep(2)
resp=client.recv(1024)
print(resp)
clientTest()
C:
char* serverListen(server *s, int *bytesWritten){
int listenRet=listen(s->socketFd, maxConnections);
if(listenRet==0){
unsigned int clientLen;
s->incomingSocket=accept(s->socketFd, (struct sockaddr*)&s->clientIn, &clientLen);
if(s->incomingSocket<0){
printf("Server Listen problem\n\tAccept issue: %i\n", s->incomingSocket);
close(s->incomingSocket);
return NULL;
}
char *buffer=(char*)calloc(s->bufferSize, sizeof(char));
int bytesRead=read(s->incomingSocket, buffer, s->bufferSize-1);
if(bytesRead<0){
printf("Server Listen Problem\n\tRead issue: %i\n", bytesRead);
free(buffer);
close(s->incomingSocket);
return NULL;
}
#ifdef DEBUG
printf("Bytes read: %i\nMessage:\t%s\n", bytesRead, buffer);
#endif
int writeRet=write(s->incomingSocket, "Message recived", 16);
if(writeRet<0){
printf("Server Listen Problem\n\tWrite issue: %i\n", writeRet);
close(s->incomingSocket);
return NULL;
}
*bytesWritten=bytesRead;
close(s->incomingSocket);
return buffer;
}
return NULL;
}
void* singleThreadServerFunc(void *params){
server *s=(server*)params;
char *retData;
int bytesWritten;
while(s->serverShouldRun){
retData=serverListen(s, &bytesWritten);
if(bytesWritten>0){
printf("%s", retData);
}
free(retData);
}
return NULL;
}
server *initServer(int port){
server *out=(server*)calloc(1, sizeof(struct server));
out->socketFd=socket(AF_INET, SOCK_STREAM, 0);
if(out->socketFd<0){
printf("Server init problem\n\tsockFd is less than 0!\n");
freeServer(out);
return NULL;
}
int opts=1;
int sockOption=setsockopt(out->socketFd, SOL_SOCKET, SO_REUSEADDR, &opts, sizeof(opts));
if(sockOption<0){
printf("Server init problem\n\tSocket Option issue\n");
freeServer(out);
return NULL;
}
out->portNumber=port;
out->serverIn.sin_family=AF_INET;
out->serverIn.sin_addr.s_addr=INADDR_ANY;
out->serverIn.sin_port=htons(out->portNumber);
memset(&out->serverIn.sin_zero, 0, sizeof(char));
int bindRet=bind(out->socketFd, (struct sockaddr*)&out->serverIn, sizeof(out->serverIn));
if(bindRet<0){
printf("Server init problem\n\tBind issue %i\n", bindRet);
freeServer(out);
return NULL;
}
out->bufferSize=1024;
pthread_create(&out->serverThread, NULL, singleThreadServerFunc, out);
return out;
}
int main(){
server *s=initServer(DefaultPort);
if(s!=NULL){
while(1){
char c[2];
scanf("%1s",c);
if(c[0]=='q')
break;
}
freeServer(s);
}
return 0;
}
I found the answer, it was in singleThreadServerFunc I did not have s->serverShouldRun set to true
Testing Linux syscall epoll using a simple parent-child program.
Expected behaviour
As the child writes a no every second, the parent should read it from the pipe and write a no every second to stdout.
Actual behaviour
The parent waits till the child writes all the nos, and then reads all data from pipe and writes to stdout. Verified by doing strace on parent. It blocks in epoll_wait.
please check README in github more information
Parent
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <error.h>
#include <errno.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/epoll.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define NAMED_FIFO "aFifo"
static void set_nonblocking(int fd) {
int flags = fcntl(fd, F_GETFL, 0);
if (flags == -1) {
perror("fcntl()");
return;
}
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
perror("fcntl()");
}
}
void errExit(char *msg) {
perror(msg);
exit(-1);
}
void printArgs(char **argv,char **env) {
for(int i=0;argv[i];i++)
printf("argv[%d]=%s\n",i,argv[i]);
for(int i=0;env[i];i++)
printf("env[%d]=%s\n",i,env[i]);
}
void PrintNos(short int max,char *name) {
int fifo_fd,rVal;
int bSize=2;
char buffer[bSize];
fifo_fd = open(NAMED_FIFO,O_RDONLY);
if(fifo_fd<0)
errExit("open");
for(short int i=0;i<max;i++) {
rVal = read(fifo_fd,buffer,bSize);
if(rVal != bSize)
errExit("read");
printf("%03d\n",i);
}
}
int main(int argc, char *argv[],char *env[]) {
//int pipe_fds_child_stdin[2] ;
int pipe_fds_child_stdout[2] ;
pid_t child_id ;
//if( pipe(pipe_fds_child_stdin) < 0 )
// errExit("pipe");
if( pipe(pipe_fds_child_stdout) < 0 )
errExit("pipe");
child_id = fork();
if( child_id > 0 ) {
const int MAX_POLL_FDS = 2;
const int BUF_SIZE = 4;
size_t readSize;
char buf[BUF_SIZE];
int status;
int epoll_fd;
int nfds ;
struct epoll_event e_e, e_events[MAX_POLL_FDS];
memset(e_events,'\0',sizeof(e_events));
memset(&e_e,'\0',sizeof(e_e));
//close(pipe_fds_child_stdin[0]);
close(pipe_fds_child_stdout[1]);
epoll_fd = epoll_create1(0);
if(epoll_fd < 0)
errExit("epoll_create1");
e_e.data.fd = pipe_fds_child_stdout[0];
e_e.events = EPOLLIN;
if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, pipe_fds_child_stdout[0], &e_e) < 0)
errExit("epoll_ctl");
while(1) {
nfds = epoll_wait(epoll_fd, e_events,MAX_POLL_FDS,-1);
if( nfds < 0)
errExit("epoll_wait");
for(int i=0;i<nfds;i++) {
if( e_events[i].data.fd == pipe_fds_child_stdout[0]) {
if( e_events[i].events & EPOLLIN) {
readSize = read(pipe_fds_child_stdout[0],buf,BUF_SIZE);
if( readSize == BUF_SIZE ) {
write(STDOUT_FILENO,buf,BUF_SIZE);
} else if(readSize == 0) { // eof
errExit("readSize=0");
} else {
errExit("read");
}
} else if( e_events[i].events & EPOLLHUP) {
printf("got EPOLLHUP on pipefd\n");
wait(&status);
exit(0);
} else {
errExit("Unexpected event flag returned by epoll_wait on waited fd");
}
} else {
errExit("epoll_wait returned non-awaited fd");
}
}
}
} else if( child_id == 0 ) {
close(0);
close(1);
//close(pipe_fds_child_stdin[1]);
close(pipe_fds_child_stdout[0]);
//dup2(pipe_fds_child_stdin[0],0);
dup2(pipe_fds_child_stdout[1],1);
execvpe(argv[1],&(argv[1]),env);
//PrintNos(100,"P");
//errExit("execvp");
} else {
errExit("fork");
}
}
Child
import sys
import time
import os
#f=open("aFifo",'r')
for x in range(10):
#try:
# val = f.read(2)
#except Exception as e:
# raise
time.sleep(1)
print(f'{x:03d}')
This is due to python buffering, which can be disabled by passing -u option to python.
After much searching and research, understood that this is due to pipe buffer. Though the client writes, it is in pipe buffer. Only after the pipe buffer is full, the kernel sends ready event on that descriptor. The minimum is pagesize, kernel doesn't allow to set below that. But it can be increased. Got to this, by changing from epoll to poll/select. After changing to poll/select the behaviour was same. Blocking though data was available in pipe.
import fcntl
import os
F_SETPIPE_SZ=1031
fds = os.pipe()
for i in range(5):
print(fcntl.fcntl(fds[0],F_SETPIPE_SZ,64))
$ python3.7 pipePageSize.py
4096
4096
This is the modified client. Appropriate changes in server too.
import time
pageSize=1024*8
for x in range(100):
time.sleep(0.5)
print(f'{x:-{pageSize}d}')
I'm trying to learn the nanomsg library.
I'm using the code examples of both versions C and Python. I'm trying to subscribe to the C service with a Python script, but nothing is happening.
Here's both of my code :
Python subscriber
from __future__ import print_function
from nanomsg import Socket, PAIR, PUB
s2 = Socket(PAIR)
while(True):
s2.connect('tcp://127.0.0.1:5555')
s2.send(b'hello nanomsg #1')
s2.send(b'hello nanomsg #2')
s2.close()
C code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <netinet/in.h> /* For htonl and ntohl */
#include <unistd.h>
#include <nanomsg/nn.h>
#include <nanomsg/pubsub.h>
/* The server runs forever. */
int server(const char *url)
{
int fd;
/* Create the socket. */
fd = nn_socket (AF_SP, NN_PUB);
if (fd < 0) {
fprintf (stderr, "nn_socket: %s\n", nn_strerror (nn_errno ()));
return (-1);
}
/* Bind to the URL. This will bind to the address and listen
synchronously; new clients will be accepted asynchronously
without further action from the calling program. */
if (nn_bind (fd, url) < 0) {
fprintf (stderr, "nn_bind: %s\n", nn_strerror (nn_errno ()));
nn_close (fd);
return (-1);
}
/* Now we can just publish results. Note that there is no explicit
accept required. We just start writing the information. */
for (;;) {
uint8_t msg[2 * sizeof (uint32_t)];
uint32_t secs, subs;
int rc;
secs = (uint32_t) time (NULL);
subs = (uint32_t) nn_get_statistic (fd, NN_STAT_CURRENT_CONNECTIONS);
secs = htonl (secs);
subs = htonl (subs);
memcpy (msg, &secs, sizeof (secs));
memcpy (msg + sizeof (secs), &subs, sizeof (subs));
rc = nn_send (fd, msg, sizeof (msg), 0);
if (rc < 0) {
/* There are several legitimate reasons this can fail.
We note them for debugging purposes, but then ignore
otherwise. */
fprintf (stderr, "nn_send: %s (ignoring)\n",
nn_strerror (nn_errno ()));
}
sleep(10);
}
/* NOTREACHED */
nn_close (fd);
return (-1);
}
/* The client runs in a loop, displaying the content. */
int client (const char *url)
{
int fd;
int rc;
fd = nn_socket (AF_SP, NN_SUB);
if (fd < 0) {
fprintf (stderr, "nn_socket: %s\n", nn_strerror (nn_errno ()));
return (-1);
}
if (nn_connect (fd, url) < 0) {
fprintf (stderr, "nn_socket: %s\n", nn_strerror (nn_errno ()));
nn_close (fd);
return (-1);
}
/* We want all messages, so just subscribe to the empty value. */
if (nn_setsockopt (fd, NN_SUB, NN_SUB_SUBSCRIBE, "", 0) < 0) {
fprintf (stderr, "nn_setsockopt: %s\n", nn_strerror (nn_errno ()));
nn_close (fd);
return (-1);
}
for (;;) {
uint8_t msg[2 * sizeof (uint32_t)];
char hhmmss[9]; /* HH:MM:SS\0 */
uint32_t subs, secs;
time_t t;
rc = nn_recv (fd, msg, sizeof (msg), 0);
if (rc < 0) {
fprintf (stderr, "nn_recv: %s\n", nn_strerror (nn_errno ()));
break;
}
if (rc != sizeof (msg)) {
fprintf (stderr, "nn_recv: got %d bytes, wanted %d\n",
rc, (int)sizeof (msg));
break;
}
memcpy (&secs, msg, sizeof (secs));
memcpy (&subs, msg + sizeof (secs), sizeof (subs));
t = (time_t) ntohl(secs);
strftime (hhmmss, sizeof (hhmmss), "%T", localtime (&t));
printf ("%s <pid %u> There are %u clients connected.\n", hhmmss,
(unsigned) getpid(), (unsigned) ntohl(subs));
}
nn_close (fd);
return (-1);
}
int main (int argc, char **argv)
{
int rc;
if ((argc == 3) && (strcmp (argv[2], "-s") == 0)) {
rc = server (argv[1]);
} else if (argc == 2) {
rc = client (argv[1]);
} else {
fprintf (stderr, "Usage: %s <url> [-s]\n", argv[0]);
exit (EXIT_FAILURE);
}
exit (rc == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
I run the C code by doing
./pubsub_demo tcp://127.0.0.1:5555 -s
Thanks for your help
The C code looks good. It comes from here.
A simpler version of C NN_PUB server and NN_SUB client also exists.
There are a few problems with presented the Python code.
1) In nanomsg we have to match behavioural-"protocols". In order to receive a NN_PUB broadcast from the C server, we have to have a matching SUB, not a PAIR, socket on the Python side.
2) Connect to the same endpoint-transport-class://address:port as NN_PUB socket nn_bind()-s to. There is no need to do it in the loop.
3) The socket has to have SUB_SUBSCRIBE option set.
4) SUB socket is for listening, it is not designed to .send() anything.
An untested Python program may look in-principle as follows:
# import appropriate modules for the nanomsg socket
from nanomsg import Socket, PUB, SUB, SUB_SUBSCRIBE
# open Python's SUB socket matching the NN_PUB socket on the C side
s2 = Socket(SUB)
# s2 should be >= 0
# connect the socket to the same endpoint as NN_PUB server
ret1 = s2.connect('tcp://127.0.0.1:5555')
# ret1 should be 0
# subscribe to everything:
ret2 = s2.set_string_option(SUB, SUB_SUBSCRIBE, '')
# ret1 should be 0
# receive messages:
while(True):
message = s2.recv()
You can also look at Python test PUB/SUB example
I hope it helps.
As a part of a project, we are trying to decrypt saved password in Google Chrome. After little digging we understand that Chrome encrypt the password using CryptProtectData function which let you encrypt the data using login user credential i.e. the encrypted data can only be decrypted on same machine by same user (other users also if appropiate parameters are provided).
Anyhow, I have previously wrote a Python script to do exactly that and it works perfectly fine.
from os import getenv, unlink
from shutil import copy
import sqlite3
import win32crypt
dbpath = "C:\Users\\"+ getenv('username') +"\AppData\Local\Google\Chrome\User Data\Default\\"
copy(dbpath + "Login Data", dbpath + "Login Data.db")
conn = sqlite3.connect(dbpath + "Login Data.db")
cursor = conn.cursor()
cursor.execute('SELECT action_url, username_value, password_value FROM logins')
for result in cursor.fetchall():
password = win32crypt.CryptUnprotectData(result[2], None, None, None, 0)[1]
print result[0] + " - " + result[1] + ":" + password
conn.close()
unlink(dbpath + "Login Data.db")
But due to project requirement, i have to code it in C language.
So i wrote the following code:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <Wincrypt.h>
#include "sqlite3.h"
static int callback(void *data, int argc, char **argv, char **azColName){
int i;
fprintf(stderr, "%s: \n", (const char*)data);
for(i=0; i<argc; i++){
if (i == 2 ){
DATA_BLOB DataIn;
DATA_BLOB DataOut;
BYTE *pbDataInput = (BYTE *) argv[i];
DWORD cbDataInput = strlen((char *) pbDataInput) + 1;
DataIn.pbData = pbDataInput;
DataIn.cbData = cbDataInput;
if (CryptUnprotectData (&DataIn, NULL, NULL, NULL, NULL, 0, &DataOut))
printf("%s\n", DataOut.pbData);
else
printf("Error number %x.\n", GetLastError());
}
// printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
int main(int argc, char* argv[])
{
sqlite3 *db;
char *zErrMsg = 0;
int rc;
char *sql;
const char* data = "Callback function called";
/* Open database */
rc = sqlite3_open("Login Data.db", &db);
if( rc ){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
return(0);
}else{
fprintf(stderr, "Opened database successfully\n");
}
/* Create SQL statement */
sql = "SELECT action_url, username_value, password_value from logins";
/* Execute SQL statement, */
rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
fprintf(stdout, "Operation done successfully\n");
}
sqlite3_close(db);
return 0;
}
It compiled correctly without any error, but the decrypted data was not correct.
C:\>gcc -o decryptor decryptor.c sqlite3.o -lcrypt32
C:\>decryptor.exe
Opened database successfully
Callback function called: Important Data
Error Number 57.
Operation done successfully
C:\>
According to System Error Codes (0-499),
0x57 is for ERROR_INVALID_PARAMETER (The parameter is incorrect)
What am I missing?
This works just fine for me as you have your crypted data in 2hex.txt (just saved it from DB Browser). Your problem was really in strlen() function, because it meets first "0" in byte sequence and stops. Just avoid it.
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <Wincrypt.h>
int main(){
FILE *fp;
DATA_BLOB DataIn;
DATA_BLOB DataOut;
char result[1000]="";
unsigned char buf[1000]="";
int tmpbuf;
int i=0;
fp=fopen("3hex.txt","rb");
printf ("Crypted data:\n");
for(i=0;(tmpbuf=getc(fp))!=EOF;i++)
{
buf[i]=tmpbuf;
if (i%16==0) printf("\n");
printf("%02X ",buf[i]);
}
DataIn.pbData=buf;
DataIn.cbData=i+1;
if (CryptUnprotectData (&DataIn, NULL, NULL, NULL, NULL, 0, &DataOut))
{
for (i=0;i<DataOut.cbData;i++)
{
result[i]=DataOut.pbData[i];
}
result[i+1]='\0';
printf("\nResult as string: %s\n", result);
}
else printf("Error number %x.\n", GetLastError());
}