Tag: python

  • C++ Version of chastehex!

    Hey, remember that chastehex program I wrote in C and several types of Assembly language? Well I finally made a C++ edition of it!

    What is the different between the C and C++ edition? Nothing at all as far as the function of it. However, I made an effort to replace all C library components with their C++ equivalents from the Standard Template library. This basically means the the console and the file input/output use only the iostream and fstream libraries.

    I am in a Programming 1 class with Full Sail University right now and I still don’t know much what I am doing with C++ but I have a good reference for C++ that I use a lot. It has all the functions from the C and C++ libraries sorted by categories.

    https://cppreference.com/index.html

    main.cpp

    #include <iostream>
    #include <fstream>
    using namespace std;
    #include "chastelib.hpp"
    
    std::fstream f;
    char bytes[17]; /*the byte buffer for hex and text dumping*/
    int count=1; /*keeps track of how many bytes were read during each row*/
    
    /*outputs the ASCII text to the right of the hex field*/
    void textdump()
    {
     int a,x=0;
    
     x=count;
     while(x<0x10)
     {
      putstring("   ");
      x++;
     }
    
     x=0;
     while(x<count)
     {
      a=bytes[x];
      if( a < 0x20 || a > 0x7E ){a='.';bytes[x]=a;}
      x++;
     }
     bytes[x]=0;
    
     putstring(bytes);
    }
    
    /*outputs up to 16 bytes on each row in hexadecimal*/
    void hexdump()
    {
     int x,address=0;
     x=0;
     f.read(bytes,16);
     count=f.gcount();
     while(count)
     {
      int_width=8;
      putint(address);
      putstring(" ");
    
      int_width=2;
      x=0;
      while(x<count)
      {
       putint(bytes[x]&0xFF);
       putstring(" ");
       x++;
      }
      textdump();
      putstring("\n");
    
      address+=count;
      f.read(bytes,16);
      count=f.gcount();
     }
    }
    
    int main(int argc, char *argv[])
    {
     int argx,x;
       
     radix=0x10; /*set radix for integer output*/
     int_width=1; /*set default integer width*/
    
     if(argc==1)
     {
      putstring
      (
       "Welcome to chastehex! The tool for reading and writing bytes of a file!\n\n"
       "To hexdump an entire file:\n\n\tchastehex file\n\n"
       "To read a single byte at an address:\n\n\tchastehex file address\n\n"
       "To write a single byte at an address:\n\n\tchastehex file address value\n\n"
      );
      return 0;
     }
    
     if(argc>1)
     {
      f.open(argv[1],ios::in|ios::out|ios::binary);
      if(!f.is_open())
      {
       printf("File \"%s\" cannot be opened.\n",argv[1]);
       return 1;
      }
      else
      {
       putstring(argv[1]);
       putstring("\n");
      }
     }
    
     if(argc==2)
     {
      hexdump(); /*hex dump only if filename given*/
     }
    
     if(argc>2)
     {
      x=strint(argv[2]);
      f.seekp(x);
     }
    
    
    
     /*read a byte at address of second arg*/
     if(argc==3)
     {
      f.read(&bytes[0],1);
      count=f.gcount();
      int_width=8;
      putint(x);
      putstring(" ");
      if(count==0){putstring("EOF");}
      else
      {
       int_width=2;
       putint(bytes[0]&0xFF);
      }
      putstring("\n");
     }
    
     /*any arguments past the address are hex bytes to be written*/
     if(argc>3)
     {
      argx=3;
      while(argx<argc)
      {
       bytes[0]=strint(argv[argx]);
       int_width=8;
       putint(x);
       putstring(" ");
       int_width=2;
       putint(bytes[0]&0xFF);
       putstring("\n");
       f.write(bytes,1);
       x++;
       argx++;
      }
     }
     
     f.close();
     return 0;
    }
    

    chastelib.hpp

    /*
     This file is a library of functions written by Chastity White Rose. The functions are for converting strings into integers and integers into strings.
     I did it partly for future programming plans and also because it helped me learn a lot in the process about how pointers work
     as well as which features the standard library provides and which things I need to write my own functions for.
    
     As it turns out, the integer output routines for C are too limited for my tastes. This library corrects this problem.
     Using the global variables and functions in this file, integers can be output in bases/radixes 2 to 36
    */
    
    /*
     These two lines define a static array with a size big enough to store the digits of an integer including padding it with extra zeroes.
     The function which follows always returns a pointer to this global string and this allows other standard library functions
     such as printf to display the integers to standard output or even possibly to files.
    */
    
    #define usl 32 /*usl stands for Unsigned String Length*/
    char int_string[usl+1]; /*global string which will be used to store string of integers. Size is usl+1 for terminating zero*/
    
     /*radix or base for integer output. 2=binary, 8=octal, 10=decimal, 16=hexadecimal*/
    int radix=2;
    /*default minimum digits for printing integers*/
    int int_width=1;
    
    /*
    This function is one that I wrote because the standard library can display integers as decimai, octai, or hexadecimal but not any other bases(including binary which is my favorite).
    My function corrects this and in my opinion such a function should have been part of the standard library but I'm not complaining because now I have my own which I can use forever!
    */
    
    char* intstr(unsigned int i)
    {
     int width=0;
     char *s=int_string+usl;
     *s=0;
     while(i!=0 || width<int_width)
     {
      s--;
      *s=i%radix;
      i/=radix;
      if(*s<10){*s+='0';}else{*s=*s+'A'-10;}
      width++;
     }
    
     return s;
    }
    
    /*
     This function prints a string using cout instead of fwrite.
     This is the best C++ representation of how my Assembly programs also work/
     It's true purpose is to be used in the putint function for conveniently printing integers, 
     but it can print any valid string.
    
     In the original C version, the putstring function was implemented with some pointer math to
     get the length of the string and then fwrite was used:
        fwrite(s,1,c,stdout);
    
     Technically this entire function could have been summed up in one statement:
        cout<<s;
    
     But where is the fun in that? I already had the logic for determining the length of the string.
     I also think that the new way of using << to write to cout is confusing because it is the left shift operator from C.
     Therefore, I wrote the function the following way to rebel against this common practice.
    */
    
    void putstring(const char *s)
    {
     int c=0;
     const char *p=s;
     while(*p++){c++;} 
     cout.write(s,c);
    }
    
    /*
     This function uses both intstr and putstring to print an integer in the currently selected radix and width
    */
    void putint(unsigned int i)
    {
     putstring(intstr(i));
    }
    
    /*
     This function is my own replacement for the strtol function from the C standard library.
     I didn't technically need to make this function because the functions from stdlib.h can already convert strings from bases 2 to 36 into integers.
     However my function is simpler because it only requires 2 arguments instead of three and it also does not handle negative numbers.
     Never have I needed negative integers but if I ever do I can use the standard functions or write my own in the future.
    */
    
    int strint(const char *s)
    {
     int i=0;
     char c;
     if( radix<2 || radix>36 ){ cout << "Error: radix " << i << " is out of range!\n"; return i;}
     while( *s == ' ' || *s == '\n' || *s == '\t' ){s++;} /*skip whitespace at beginning*/
     while(*s!=0)
     {
      c=*s;
      if( c >= '0' && c <= '9' ){c-='0';}
      else if( c >= 'A' && c <= 'Z' ){c-='A';c+=10;}
      else if( c >= 'a' && c <= 'z' ){c-='a';c+=10;}
      else if( c == ' ' || c == '\n' || c == '\t' ){return i;}
      else{ cout << "Error: " << c << " is not an alphanumeric character!\n";return i;}
      if(c>=radix){ cout << "Error: " << c << " is not a valid character for radix " << radix; return i;}
      i*=radix;
      i+=c;
      s++;
     }
     return i;
    }
    
    /*
     Those four functions above are pretty much the entirety of chastelib.
     While there may be extensions written for specific programs, these functions are essential for absolutely every program.
     The only reason you would not need them is if you only output numbers in decimal or hexadecimal, because printf in C can do all that just fine.
    */
    
  • DOS Assembly putstring function

    This is a small program which uses the putstring function I wrote. This function is one of 4 ultimate functions I have created which make up “chastelib”. DOS programming is simpler than Windows and is not that different from Linux in that system calls are done with an interrupt.

    org 100h
    
    main:
    
    mov ax,text
    call putstring
    
    mov ax,4C00h
    int 21h
    
    text db 'Hello World!',0Dh,0Ah,0
    
    ;This section is for the putstring function I wrote.
    ;It will print any zero terminated string that register ax points to
    
    stdout dw 1 ; variable for standard output so that it can theoretically be redirected
    
    putstring:
    
    push ax
    push bx
    push cx
    push dx
    
    mov bx,ax                  ;copy ax to bx for use as index register
    
    putstring_strlen_start:    ;this loop finds the length of the string as part of the putstring function
    
    cmp [bx], byte 0           ;compare this byte with 0
    jz putstring_strlen_end    ;if comparison was zero, jump to loop end because we have found the length
    inc bx                     ;increment bx (add 1)
    jmp putstring_strlen_start ;jump to the start of the loop and keep trying until we find a zero
    
    putstring_strlen_end:
    
    sub bx,ax                  ; sub ax from bx to get the difference for number of bytes
    mov cx,bx                  ; mov bx to cx
    mov dx,ax                  ; dx will have address of string to write
    
    mov ah,40h                 ; select DOS function 40h write 
    mov bx,[stdout]            ; file handle 1=stdout
    int 21h                    ; call the DOS kernel
    
    pop dx
    pop cx
    pop bx
    pop ax
    
    ret
    

    Anyone can assemble and run this source code, but you will need a DOS emulator like DOSBox in order for it to work. In fact, I have a video showing me assembling and running it inside of DOSBox.

    Lately I have been having a programming phase and am working on a book about programming in DOS. There is no money involved in this because nobody except nerds like me care about DOS. Speaking of nerds, if you follow my blog, don’t forget that this site was set up for teaching Chess. Leave me a comment if you play Chess online or live in Lee’s Summit. I am still playing Chess every day although some of my time has been taken up with programming in Assembly language because it is so much fun.

    If you like this post, you may be interested in my much longer post/book that is all about Assembly programming in DOS.

  • Chastity’s Hex Compare Tool

    Welcome to Chastity’s Hex Compare program also known as “chastecmp”. Enter two filenames as command line arguments such as:

    ./chastecmp file1.txt file2.txt

    It works for any binary files too, not just text. In fact for text comparison you want entirely different tools. This tool can be used to find the tiny differences between files in hexadecimal. It shows only those bytes which are different. I wrote it as a solution to a reddit user who asked how to compare two files in hexadecimal.

    It is an improvement over the Linux “cmp” tool which displays the offsets in decimal and the bytes in octal. Aside from using two different bases in the data, it falls short of usefulness because there are more hex editors than octal editors.

    Here are also some graphical tools I can recommend if you are looking for a GUI instead of my command line program.

    vbindiff
    wxHexeditor

    Below is the full source code:

    #include <stdio.h>
    #include <stdlib.h>
     
    int main(int argc, char *argv[])
    {
     int argx,x;
     FILE* fp[3]; /*file pointers*/
     int c1,c2;
     long flength[3]; /*length of the file opened*/
       
     /*printf("argc=%i\n",argc);*/
    
     if(argc<3)
     {
      printf("Welcome to Chastity's Hex Compare program also known as \"chastecmp\".\n\n");
      printf("Enter two filenames as command line arguments such as:\n");
      printf("%s file1.txt file2.txt\n",argv[0]);
      return 0;
     }
    
     argx=1;
     while(argx<3)
     {
       fp[argx] = fopen(argv[argx], "rb"); /*Try to open the file.*/
       if(!fp[argx]) /*If the pointer is NULL then this becomes true and the file open has failed!*/
       {
        printf("Error: Cannot open file \"%s\": ",argv[argx]);
        printf("No such file or directory\n");
        return 1;
       }
      /*printf("File \"%s\": opened.\n",argv[argx]);*/
    
      printf("fp[%X] = fopen(%s, \"rb\");\n",argx,argv[argx]);
      argx++;
     }
    
     printf("Comparing files %s and %s\n",argv[1],argv[2]);
    
     argx=1;
     while(argx<3)
     {
      fseek(fp[argx],0,SEEK_END); /*go to end of file*/
      flength[argx]=ftell(fp[argx]); /*get position of the file*/
      printf("length of file fp[%X]=%lX\n",argx,flength[argx]);
      fseek(fp[argx],0,SEEK_SET); /*go back to the beginning*/
      argx++;
     }
    
     x=0;
     while(x<flength[1])
     {
      c1 = fgetc(fp[1]);
      c2 = fgetc(fp[2]);
      if(c1!=c2)
      {
       printf("%08X: %02X %02X\n",x,c1,c2);
      }
      x++;  
     }
    
     argx=1;
     while(argx<3)
     {
      fclose(fp[argx]);
      printf("fclose(fp[%X]);\n",argx);
      argx++;
     }
    
     return 0;
    }