Extended Read Sectors From Drive (INT 13h AH=42h) - c

I am trying to read 1 block of first hard drive into the memory. I tried with different LBAs but it loads spaces in to the buffer. In following code, i added for loop so that i can see if it loads anything else than just spaces. Do you guys know why it's only loading spaces into the buffer?
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <dos.h>
#include <bios.h>
struct DAP
{
unsigned char size;
unsigned char reserved1;
unsigned char blocks;
unsigned char reserved2;
unsigned char far *buffer;
unsigned long int lbalod;
unsigned long int lbahid;
} dap;
char st[80];
unsigned char buf[512];
FILE *fptr;
unsigned long int itrations = 16450559; //10gb
unsigned long int i = 0;
void main(void)
{
clrscr();
for(; i<itrations; i++)
{
dap.size = sizeof(dap);
dap.reserved1 = 0;
dap.blocks = 1;
dap.reserved2 = 0;
dap.buffer = (unsigned char far *)MK_FP(_DS, buf);
dap.lbalod = i;
dap.lbahid = 0;
_AH = 0x42;
_DL = 0x80;
_SI = (unsigned int)&dap;
geninterrupt(0x13);
printf("%lu: %s\n", i, buf);
}
}
It's using Borland Turbo C over VMWare virtual machine that is setup with WinXP. I have also tried the same on DOSBOX on Windows 7. Any help would be much appreciated.

These are only my suggestions in the hope that they help your debugging.
Print sizeof(dap) to ensure that it is indeed 16
Insert memset(buf, 'A', sizeof(buf)); before you issue INT 13h so that you can check buf is modified or not
Try printf("%lu: [%s]\n", i, buf); instead, because when buf contains \0 around its head printf stops there. The braces should work as marks.
Print _AH and _CF which should contain return codes of INT 13h

#include <dos.h>
#include <bios.h>
struct DAP
{
unsigned char size;
unsigned char reserved1;
unsigned char blocks;
unsigned char reserved2;
unsigned char far *buffer;
unsigned long int lbalod;
unsigned long int lbahid;
} dap;
char st[50];
unsigned char buff[256];
FILE *fptr;
main(void)
{
puts ("enter the lba low double word: ");
gets (st);
dap.lbalod=atol(st);
puts ("enter the lba high double word: ");
gets (st);
dap.lbahid=atol(st);
dap.size=16;
dap.reserved1=0;
dap.blocks1;
dap.reserved2=0
dap.buffer = (unsigned char far *)MK FP(DS.buf);
_AH = 0x42;
_DL = 0x80;
_SI = (unsigned int)%dap;
geninterrupt(0x13);
puts ("enter the path: ");
gets(st);
fptr = fopen(st, "wb");
fwrite(buf,256,1,fptr);
fclose(fptr);
}
i am getting statement missing error on this line dap.buffer = (unsigned char far *)MK_FP(_DS, buf);

Related

fgetc() and feof() throws segfault with big files

I'm trying to write a program that manipulates ppm image files, works fine with relatively small files up to 622x1023 or so, but with a file any bigger the program throws a segfault error.
I have isolated the problem to this function:
void img2list(FILE *fp,int x,int y,int bd,int *resultado,long tamano){
int dimx=x,dimy=y;
int bitDepth=bd;
long numeroPixeles=(dimx*dimy*bitDepth);
int con=0;
int pixels[numeroPixeles];
while (!feof(fp)){
pixels[con]=fgetc(fp);
con++;
}
memcpy(resultado,pixels,tamano);
}
specifically to:
feof(fp)
and
fgetc(fp)
I'm compiling the code with this command:
gcc main.c -o pim
And I'm running Ubuntu 19.04 on a core i7 5820k with 16GB of RAM
Here's the entire code:
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int * getMeta(FILE *fp){
static int meta[3];
size_t len = 0;
char * line = NULL;
char delim[] = " ";
getline(&line,&len,fp);
getline(&line,&len,fp);
char *ptr1 = strtok(line, delim);
char *ptr2 = strtok(NULL, delim);
sscanf(ptr1, "%d", &meta[0]);
sscanf(ptr2, "%d", &meta[1]);
getline(&line,&len,fp);
char *ptr3 = strtok(line, delim);
sscanf(ptr3, "%d", &meta[2]);
return meta;
}
void img2list(FILE *fp,int x,int y,int bd,int *resultado,long tamano){
int dimx=x,dimy=y;
int bitDepth=bd;
long numeroPixeles=(dimx*dimy*bitDepth);
int con=0;
int pixels[numeroPixeles];
while (!feof(fp)){
pixels[con]=fgetc(fp);
con++;
}
memcpy(resultado,pixels,tamano);
}
void list2file(int *pixeles,int x,int y,int bitDepth, char nombre[]){
int dimx = x, dimy = y;
long numeroPixeles = dimx*dimy*bitDepth;
FILE *archivo = fopen(nombre, "wb"); /* b - binary mode */
(void) fprintf(archivo, "P6\n%d %d\n255\n", dimx, dimy);
for(long i=0;i<numeroPixeles;i++){
(void) fprintf(archivo,"%c",(char)pixeles[i]);
}
(void) fprintf(archivo,"\n");
(void) fclose(archivo);
}
int main(void){
int *meta;
int values,dimx,dimy;
int bitDepth=3;
FILE *fp = fopen("test.ppm","rb");
meta=getMeta(fp); // Dimenciones de la imagen
dimx = meta[0];
dimy = meta[1];
values = meta[2];
printf("dimencion en x: %d\n",dimx);
printf("dimencion en y: %d\n",dimy);
printf("cantidad de valores por pixel: %d\n",values);
long tamano=(dimx*dimy*bitDepth*sizeof(int));
int *pixeles=malloc(tamano);
img2list(fp,dimx,dimy,3,pixeles,tamano);
char nombre[]="pena.ppm";
list2file(pixeles,dimx,dimy,bitDepth,nombre);
(void) fclose(fp);
return EXIT_SUCCESS;
}
Thanks.
This:
int pixels[numeroPixeles];
is a stack overflow unless numeroPixeles is bounded by a small constant. Allocating large objects on the stack admits no way to distinguish success/failure; your program just blows up (and possibly yields code execution under the control of whoever authored the data you're processing). To work with arbitrary-size data like this you need malloc where you can check for success.

Why does this code have a "EOF in inline file" error and what can I do to fix it?

I got this source code straight from the manufacturer and I cannot get it to compile. I always get a EOF in file error.
I am using Pelles C to compile on Windows 10 X64. It seems that it should be pretty straight forward but I cant figure it out. It should be a program that I supply a string and it should print a crc
int main(){
str scan = "";
printf("Enter String");
fgets(scan, 10, stdin);
calc_crc_half(scan, 4);
return(0);
}
INT16U cal_crc_half(INT8U far *pin, INT8U len){
INT16U crc;
INT8U da;
INT8U far *ptr;
INT8U bCRCHign;
INT8U bCRCLow;
INT16U crc_ta[16]={
0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,
0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef
};
ptr=pin;
crc=0;
while(len--!=0)
{
da=((INT8U)(crc>>8))>>4;
crc<<=4;
crc^=crc_ta[da^(*ptr>>4)];
da=((INT8U)(crc>>8))>>4;
crc<<=4;
crc^=crc_ta[da^(*ptr&0x0f)];
ptr++;
}
bCRCLow = crc;
bCRCHign= (INT8U)(crc>>8);
if(bCRCLow==0x28||bCRCLow==0x0d||bCRCLow==0x0a){
bCRCLow++;
}
if(bCRCHign==0x28||bCRCHign==0x0d||bCRCHign==0x0a){
bCRCHign++;
}
crc = ((INT16U)bCRCHign)<<8;
crc += bCRCLow;
printf(crc);
return(crc);
}
I expect the output to be a four character string.
Since you say that you got this code "straight from the manufacturer", presumably you need the CRC's generated using this specific implementation for a particular purpose. This code will work. If you can't get it to compile, you're not doing something correctly in the Pelles C IDE. If that's the case, you might try using a wizard to generate a simple "Hello World" program, and when you get it to compile and run, replace that code with this.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
unsigned short cal_crc_half(unsigned char *pin, size_t len){
unsigned short crc;
unsigned char da;
unsigned char *ptr;
unsigned char bCRCHign;
unsigned char bCRCLow;
unsigned short crc_ta[16]={
0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,
0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef
};
ptr=pin;
crc=0;
while(len--!=0)
{
da=((unsigned char)(crc>>8))>>4;
crc<<=4;
crc^=crc_ta[da^(*ptr>>4)];
da=((unsigned char)(crc>>8))>>4;
crc<<=4;
crc^=crc_ta[da^(*ptr&0x0f)];
ptr++;
}
bCRCLow = (unsigned char)crc;
bCRCHign= (unsigned char)(crc>>8);
if(bCRCLow==0x28||bCRCLow==0x0d||bCRCLow==0x0a){
bCRCLow++;
}
if(bCRCHign==0x28||bCRCHign==0x0d||bCRCHign==0x0a){
bCRCHign++;
}
crc = ((unsigned short)bCRCHign)<<8;
crc += bCRCLow;
return crc;
}
int main(int argc, char* argv[])
{
char word[256];
unsigned short crc;
puts("Type each word and hit 'Enter'. Enter 'quit' to exit.\n");
while (fgets(word, 256, stdin) != NULL) {
if (strcmp(word, "quit\n") == 0) break;
crc = cal_crc_half(word, strcspn(word, "\n"));
printf("%X\n", crc);
}
return 0;
}
Code lacks a proper buffer for reading. Attempting to write to the string literal """ is undefined behavior (UB). #Shawn
int main() {
// str scan = "";
char scan[11];
printf("Enter String");
fgets(scan, 10, stdin);
calc_crc_half(scan, 4);
The code will calculate the CRC based on input potentially including the '\n'.
I expect OP needs a front end more like
int main(void) {
char scan[100]; // be more generous in input possibilities.
printf("Enter String\n");
if (fgets(scan, sizeof scan, stdin)) {
scan[strcspn(scan, "\n")] = '\0'; // lop off potential \n
calc_crc_half(scan, strlen(scan));
}

OpenSSL rsa routines:RSA_padding_check_PKCS1_type_2:pkcs decoding error

I'm trying to encrypt/decrypt an AES key/iv using RSA encryption algorithm using openssl in C.
The decryption is working before storing the encrypted data into the file . But the decryption threw an error while decrypting the same encrypted data stored on the file.
Here is my code:
#include <stdio.h>
#include <stdbool.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <string.h>
int padding = RSA_PKCS1_PADDING;
#define RSA_KEY_Size 384;
#define AES_256_KEY_SIZE 32;
// testing encryption/decryption
int func(const char* pubkeyfile, unsigned char *key, unsigned char *iv)
{
unsigned char *encryptedkey = (unsigned char*)malloc(RSA_KEY_Size);
unsigned char *encryptediv = (unsigned char*)malloc(RSA_KEY_Size);
unsigned char *decryptedkey = (unsigned char*)malloc(AES_256_KEY_SIZE);
unsigned char *decryptediv = (unsigned char*)malloc(AES_256_KEY_SIZE);
int result1 = rsaEncrypt(key, pubkeyfile, encryptedkey);
int result2 = rsaEncrypt(iv, pubkeyfile, encryptediv);
serialize(encryptedkey, encryptediv);
///////tested here, this part working fine
int r1 = rsaDecrypt(encryptedkey, privkeyfile, decryptedkey);
int r2 = rsaDecrypt(encryptediv, privkeyfile, decryptediv);
///////////////////////////////
unsigned char *getkey = (unsigned char*)malloc(RSA_KEY_Size);;
unsigned char *getiv = (unsigned char*)malloc(RSA_KEY_Size);;
deserialize(getkey, getiv);
unsigned char *ikey = (unsigned char*)malloc(AES_256_KEY_SIZE);
unsigned char *iiv = (unsigned char*)malloc(AES_256_KEY_SIZE);
//////////tested here, failed to decrypt after taking encrypted data from a file/////////////////
int r22 = rsaDecrypt(getiv, privkeyfile, iiv);
int r21 = rsaDecrypt(getkey, privkeyfile, ikey);
//////////////////////////////////////////////////
return 0;
}
typedef struct item {
uint8_t keyivlen;
char keyiv[RSA_KEY_Size];
struct item *next;
} list;
int serialize(unsigned char* key, unsigned char* iv)
{
list *ptr;
char *buffer;
int listLength;
list first, second;
ptr = &first;
FILE *filePtr;
memcpy(first.keyiv, key, strlen(key));
first.keyivlen = strlen(first.keyiv);
first.next = &second;
memcpy(second.keyiv, iv, strlen(iv));
second.keyivlen = strlen(second.keyiv);
second.next = 0;
listLength = listSize(ptr);
buffer = (char *)malloc(listLength);
serializeList(ptr, buffer);
filePtr = fopen("example.data", "wb+");
fwrite(buffer, listLength, 1, filePtr);
fclose(filePtr);
free(buffer);
return 0;
}
int deserialize(unsigned char* key, unsigned char* iv)
{
FILE *filePtr;
int listLength = 0;
int done = 0;
uint8_t arrayLen;
unsigned char *buffer;
int i = 0;
listLength = fileSize("example.data");
filePtr = fopen("example.data", "rb");
while (done < listLength) {
fread(&arrayLen, 1, 1, filePtr);
buffer = (unsigned char *)malloc(arrayLen + 1);
fread(buffer, arrayLen, 1, filePtr);
buffer[arrayLen] = '\0';
if (i == 0)
{
memcpy(key, buffer, arrayLen + 1);
}
else
{
memcpy(iv, buffer, arrayLen + 1);
}
//addToList(arrayLen, buffer);
done += arrayLen + 1;
i++;
free(buffer);
}
//printList(start);
return 0;
}
Here is the error:
error:0407109F:rsa routines:RSA_padding_check_PKCS1_type_2:pkcs decoding error
error:04065072:rsa routines:rsa_ossl_private_decrypt:padding check failed
And it fails in:
int r22 = rsaDecrypt(getiv, privkeyfile, iiv);
int r21 = rsaDecrypt(getkey, privkeyfile, ikey);
What could be the reason for this error?
arrayLen is only uint8_t which fits at most 255 , so your deserialised data is too short. You need RSA_KEY_Size bytes.

Segmentation fault around MD5 code

While I am running this md5 code, it is taking maximum 64 characters length of input at run time. Whenever I am giving more than 64 characters, it is showing
Inconsistency detected by ld.so: dl-fini.c: 205: _dl_fini: Assertion ns != 0 || i == nloaded failed!
I need to hash nearly 10kb of input (only string). Do I need to change anything in the header file? Can anyone tell me solution please?
md5.h
#ifndef HEADER_MD5_H
#define HEADER_MD5_H
#include <openssl/e_os2.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef OPENSSL_NO_MD5
#error MD5 is disabled.
#endif
/*
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* ! MD5_LONG has to be at least 32 bits wide. If it's wider, then !
* ! MD5_LONG_LOG2 has to be defined along. !
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*/
#if defined(__LP64__)
#define MD5_LONG unsigned long
#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
#define MD5_LONG unsigned long
#define MD5_LONG_LOG2 3
/*
* _CRAY note. I could declare short, but I have no idea what impact
* does it have on performance on none-T3E machines. I could declare
* int, but at least on C90 sizeof(int) can be chosen at compile time.
* So I've chosen long...
* <appro#fy.chalmers.se>
*/
#else
#define MD5_LONG unsigned long
#endif
#define MD5_CBLOCK 64
#define MD5_LBLOCK (MD5_CBLOCK/2)
#define MD5_DIGEST_LENGTH 16
typedef struct MD5state_st
{
MD5_LONG A,B,C,D;
MD5_LONG Nl,Nh;
MD5_LONG data[MD5_LBLOCK];
unsigned int num;
} MD5_CTX;
#ifdef OPENSSL_FIPS
int private_MD5_Init(MD5_CTX *c);
#endif
int MD5_Init(MD5_CTX *c);
int MD5_Update(MD5_CTX *c, const void *data, size_t len);
int MD5_Final(unsigned char *md, MD5_CTX *c);
unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md);
void MD5_Transform(MD5_CTX *c, const unsigned char *b);
#ifdef __cplusplus
}
#endif
#endif
md5.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "md5.h"
char *pt(char *, int );
int main(int argc, char **argv)
{
char *in;
char *out;
printf("ENter the string\n");
scanf("%[^\n]s",in);
size_t len; //unsigned long len; size_t len;
len = printf("len is %d\n",strlen(in));
out = pt(in, len);
printf("MD5 is\t: %s\n", out);
free(out);
//return 0;
}
char *pt(char *str, int length)
{
int n;
MD5_CTX c;
unsigned char digest[16];
char *output = (char*)malloc(33);
MD5_Init(&c);
MD5_Update(&c, str, length);
MD5_Final(digest, &c);
for (n = 0; n < 16; ++n)
{
sprintf(&output[n*2], "%02x", (unsigned int)digest[n]);
}
return output;
}
Problem 1
For this statement:
scanf("%[^\n]s",in);
When I compile it using the -Wall flag, I get the warning:
warning: 'in' is used uninitialized in this function [-Wuninitialized]
scanf("%[^\n]s",in);
^
As you see, in is not pointing to any location in your memory, so you first need to allocate some memory either with an array or malloc():
char in[500]; //or a higher value
char *out;
printf("Enter the string\n");
scanf("%499[^\n]s", in);
printf("\nin = .%s.\n", in);
or
char *in;
char *out;
in = malloc(500); //or a higher value
printf("Enter the string\n");
scanf("%499[^\n]s", in);
printf("\nin = .%s.\n", in);
Possible problem 2
You are assigning the return from printf() to the variable len.
len = printf("len is %d\n",strlen(in));
Return value printf:
Upon successful return, it returns the number of characters printed (excluding the null byte used to end output to strings).
Assuming you want the variable len to contain the length of the string in and not the number of characters printed by printf("len is %d\n",strlen(in)), you might want to assign the return from strlen() first:
len = strlen(in);
printf("len is %d\n", len);

C output Wav file didn't produce any sound

I tried to create a c code that produce 10 sec of C note. But it seem the output .wav file didn't produce any sound.
I'm still new in C programming and it would be helpful if you can point my mistakes.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
//music note
#define C 261.6256
#define TIME 10
#define POINT 20
#define AMP 10000
#define c 5
//wav file header
typedef struct
{
char ChuckID[4];
unsigned long ChuckSize;
char format[4];
char subChunk1ID[4];
unsigned long SubChunk1Size;
unsigned short AudioFormat;
unsigned short NumChannels;
unsigned long SampleRate;
unsigned long ByteRate;
unsigned short block_allign;
unsigned short bits_per_sample;
char data[4];
unsigned long data_size;
/*char riff_tag[4];
int riff_length;
char wave_tag[4];
char fmt_tag[4];
int fmt_length;
short audio_format;
short num_channels;
int sample_rate;
int byte_rate;
short block_align;
short bits_per_sample;
char data_tag[4];
int data_length;*/
} wavheader;
int main(int argc, char **argv)
{
wavheader wave = {"RIFF",1764036,"WAVE","fmt",16,1,1,44100,176400,4,32,"data",1764000};
float data;
float f = C;
int fs = 44100;
int k;
float *buff;
FILE *out_file = fopen("ongaku.wav","w");
buff = (float*)malloc(sizeof(float)*fs*TIME);
for (k = 0; k<(int)(TIME*fs); k++)
{
data=AMP*sin(2*M_PI*f*k/fs);
//printf("%f\n",data);
}
fwrite(buff,sizeof(float),fs*TIME,out_file);
return 0;
}
I have this working with 8-bit data but unsuccessful with 12/16-bit let alone float data. One thing that's essential, is not to hard code buffer sizes in the header. Other points to watch out for are endian-ness (I happened not to need to adjust), and structure packing (ditto). My use of BPS/8 would also come unstuck when working with 12-bit data.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define FREQ 261.6256 // C
//#define FREQ 440.0 // A
#define M_PI 3.14159265358979323846
#define TIME 10
#define AMP 64.0 // don't use max volume
#define MID 128.0 // 8-bit is range 0..255
//#define MID 0.0 // 16-bit is range -32767.. 32767
#define BPS 8
#define CHANNS 1
#define RATE 44100
//wav file header
typedef struct {
char ChuckID[4];
unsigned long ChuckSize;
char format[4];
char subChunk1ID[4];
unsigned long SubChunk1Size;
unsigned short AudioFormat;
unsigned short NumChannels;
unsigned long SampleRate;
unsigned long ByteRate;
unsigned short block_allign;
unsigned short bits_per_sample;
char data[4];
unsigned long data_size;
} wavheader;
int main(int argc, char **argv)
{
int k, samples = RATE * TIME;
double data;
FILE *out_file;
unsigned char *buff;
wavheader wave = {
"RIFF",
36 + samples * CHANNS * BPS/8,
"WAVE",
"fmt ", // "fmt" was error in OP
16,
1,
CHANNS,
RATE,
RATE * CHANNS * BPS/8,
CHANNS * BPS/8,
BPS,
"data",
samples * CHANNS * BPS/8
};
buff = malloc(BPS/8 * samples);
out_file = fopen("ongaku.wav","w");
fwrite(&wave, sizeof(wave), 1, out_file);
for (k=0; k<samples; k++) {
data = MID + AMP * sin(2 * M_PI * FREQ * TIME * k / (double)samples);
buff[k] = (unsigned char)floor(data+0.5);
}
fwrite(buff, BPS/8, samples, out_file);
fclose (out_file);
free (buff);
return 0;
}
Put some data into buff, I guess your data variable is holding that value. and after that
if everything else is working correctly, use
fflush(out_file);
or use
fclose(out_file);

Resources