mycontroller – DMA

This is part of a project to build a complete, functional, extremely basic microcontroller. It is built using multimedia logic.

This section is a simulated very simplified DMA.

Example Run

The test of writing back and forth bytes seems to work.

Also, the example from the lab specification seems to work. Namely:

Download:

  • Select head 1, track 2, sector 3, block 4 on the disk.
  • Select address AB on the RAM.
  • Select 6 bytes to transfer.
  • Select download.
  • Disable the master clear.
  • Hit the transfer button. The yellow download LED should illuminate.
  • Hit the clock at least 7 times. Your transfer should stop after the 6th cycle, illuminate the green completion LED, and deactivate the yellow download LED.
  • You should see 6 different bytes transfer from disk blocks 4 through 9 from head 1, track 2, sector 3 to RAM addresses AB through B0, respectively. The particular bytes depend on how you organized the address space on your “disk.”

Upload:

  • Select head 2, track 3, sector 4, block 5 on the disk.
  • Select address AC on the RAM.
  • Select 2 bytes to transfer.
  • Select upload.
  • Hit the transfer button. The yellow upload LED should illuminate.
  • Hit the clock at least 3 times. Your transfer should stop after the 2nd cycle, illuminate the green completion LED, and deactivate the yellow upload LED.
  • You should see 2 bytes transfer from RAM addresses AC and AD to disk blocks 5 and 6 on head 2, track 3, sector 4.
  • These should be the second and third bytes you saw in the download example.

Known Issues

You can’t have reads/writes across different tracks or heads, which will produce (perhaps to the user) unexpected results, overwriting the same sectors rather than proceeding to the next track. In short, reading/writing across tracks requires multiple reads/writes.

I made a conscious decision to not worry about the clock wrapping around at this point. If the clock does wrap around, it may screw stuff up.

Screen Shots

Here is a link to the source.

Matrix Multiplication Optimization in C++

This is an example of dynamic programming. This requires a basic understanding of linear algebra and includes a program written in C++.

Problem

When multiplying matrices together, the dimensions of the matrices to be multiplied must be compatible. The columns of the first matrix must be equal to the rows in the second matrix. For example, consider the following compatible chain of matrices. Let A_x denote a matrix and the letters inside the brackets represent the ROWS and COLUMNS of that matrix respectively.

A_1[a][b] * A_2[b][c] * A_3[c][d]… *A_size[y][z]

When multiplying two matrices together, the resultant matrix has the ROWS dimension of the first matrix, and the COLUMNS dimension of the second matrix. For example

A_1[a][b] *A_2[b][c] = A_result[a][c]

So extending this idea, it is the case that

A_1[a][b] * A_2[b][c] * A_3[c][d]… *A_n[y][z] = A_result[a][z]

Matrix multiplication is not commutative. This is intuitive – since the columns in A_n-1Â must equal the rows in A_n, you can’t just switch the order around.

A_1 * A_2 * A_3 is probably NOT equal to A_1 * A_3 * A_2

However, Matrix multiplication is associative. Associativity signifies that the order the multiplication is done can change.

((A_1 * A_2) * A_3) == (A_1 * ( A_2 * A_3))

When multiplying a chain of matrices together, one way is generally more efficient than others. The cost (number of operations that must be done) of multiplying two matrices in the chain above can be calculated as follows:

cost(A_n-1[a][b] * A_n[b][c]) == a * b * c

Example:

Say we have the following chain of matrices to multiply together.

A_1[3][5] * A_2[5][100] * A_3[100][2]

First let’s group the array as follows:

((A_1[3][5] * A_2[5][100] ) * A_3[100][2])

multiplying A_1 with A_2 will cost 3 * 5 * 100 or 1,500, and the resultant is a 3 by 100 matrix We are then left with the following multiplication to do.

A_res1[3][100] * A_3[100][2]

This will cost 3 * 100 * 2 which is 600.

So the total cost of multiplying the matrices like this is 1,500 + 600 which is 2,100

Now let’s group the array as follows and compare it with the previous result.

(A_1[3][5] * (A_2[5][100] * A_3[100][2]))

This will cost (5*100*2) which is 1,000 + (3*5*2) which is 15. So the total cost of this multiplication is 1,015.

This is less than half as expensive as the first option. And this is not a contrived example – this is typical. Given a chain of matrices and their corresponding dimensions, it is possible to find the optimal way to multiply these matrices together.

Solution

The obvious way to find the optimal order of multiplying a chain of matrices together would be to simply calculate the cost of each possible solution and then compare these costs (brute force). This would be easy enough if there are only small chains. However, it turns out that this would require around 2n computations where n is the number of matrices, which is not practical for large n.

The reason the cost is so high is that there are many computations that are re-done. An improved solution would be to create a table which keeps track of all the sub-optimal solutions, and uses these to calculate the final cost. Using a table, the cost can be reduced to n3, which is substantially better. This is the method which is used in the below program.

The below program inputs the dimensions of a number of arrays. For example, if there is the following chain of arrays:

A_1[3][5] * A_2[5][100] * A_3[100][2]

The dimensions can be input as:

5 x 100

The program will then calculate the best way to multiply the matrix in n3 time. In the example above, it would output,

(A_1 * (A_2 * A_3))

Also, the program will output the tables that are used to calculate this optimal cost. Because of the size of the screen, the output will only be neat for small chains of matrices. Here’s the source.

/************************************************************************************************
*  Matrix multiplication optimizer
*  by Richard Lundeen - webstersProdigy.net
*
*  This program optimizes the order in which a chain of matrices are multiplied together in
*  O(n^3).  It prints out tables for documentation purposes - although these are not necessary
*  to understand the final grouping
*
**************************************************************************************************/

#include <iostream>

using namespace std;

void printdobArray(int** array, int row, int col);
void printOptimalParens(int** kArray, int i, int j);

int main()
{
   int numMat;
   cout<<"**********************************************************************"<<endl
       <<"Welcome to the matrix optimization program.  This program calculates"<<endl
       <<"the optimal way to multiply a series of matrices together"<<endl
       <<"*********************************************************************"<<endl;
   cout<<"Please enter the Number of Matricies: ";
   cin>>numMat;

   int *p;
   int psize = numMat + 1;
   p = new int[psize];

   cout<<"------------------------------------------------------------------------"<<endl
       <<"Now please enter dimensions.  \nFor example, if you were multiplying three matricies "<<endl
       <<"with the respective dimensions 3x1  1x1000 and 1000x13, you would enter '3', '1', '1000', '13'."<<endl
       <<"------------------------------------------------------------------------"<<endl<<endl;
   for(int i = 0; i < psize; i++)
   {
      cout<<"dimension "<<i<<" : ";
      cin>>p[i];
   }

   //an array which holds the cost table
   int **cost;
   cost = new int*[psize];  // sets up an array of row pointers
   for(int i =0; i < psize; i++)
   {
       cost[i] = new int[psize]; // allocates each row of the grades array
   }

   //an array which holds the splits
   int ** kArray;
   kArray = new int*[psize];
   for(int i=0; i<(psize); i++)
   {
      kArray[i]=new int[psize];
   }

   for(int length = 1; length < numMat; length++)
   {
      for(int i = 1; i<numMat-length + 1; i++)
      {

         int j = i+ length;
	 int tempCost;
	 int k = i;
	 int minCost = cost[i][k] + cost[k+1][j] + p[i-1]*p[k]*p[j];
	 int kay = i;
	 for(; k<j; k++)
	 {
	   tempCost = cost[i][k] + cost[k+1][j] + p[i-1]*p[k]*p[j];
	   if(tempCost<minCost)
	   {
	      minCost = tempCost;
	      kay = k;
	   }
	 }

	cost[i][j] = minCost;
	kArray[i][j] = kay;
      }
   }

   cout<<"\nTotal Cost Table\n************************************"<<endl;
   printdobArray(cost, psize, psize);

   cout<<"Corresponding K-Table\n***********************************"<<endl;
   printdobArray(kArray,psize,psize);

   cout<<endl<<endl;
   cout<<"This corresponds to the following multiplication chain"<<endl;
   printOptimalParens(kArray, 1, numMat);
   cout<<endl;
   return 0;
}

void printdobArray(int** array, int row, int col)
{
   for(int i = 1; i<row; i++)
   {
      for(int j=1; j<col; j++)
         cout<<array[i][j]<<"\t|\t";
      cout<<endl;
   }
}

void printOptimalParens(int** kArray, int i, int j)
{
   if(i==j)
    {
       cout<<"A"<<i<<" ";
    }
    else
    {
       cout<<"(";
       printOptimalParens(kArray,i, kArray[i][j]);
       printOptimalParens(kArray, kArray[i][j] + 1, j);
       cout<<")";
    }
}

This program was compiled using gcc.

Links to Additional Information

Wikipedia-Dynamic
Programming

Wikipedia-Matrix
Chain Multiplication

McGraw-Hill
(check out the Pseudo code for matrix chain
multiplication)

http://www.ics.uci.edu/~dan/class/161/notes/6/Dynamic.html

print shell code

From the book “Buffer Overflow Attacks” by Foster and others, I came across this very handy tool for testing developing shellcode.  It takes your assembly and puts it into a well commented C array to be tested by execution or simply printing to the screen.

To compile thes program, type gcc -o printshell printshellcode.c

Now, if you want to try out your shellcode assembly,

  • Type the instructions in a .S file
  • Execute nasm -o <filename> <filename>.S
    • To print the shellcode use printshellcode -p <filename>.
    • To execute the shellcode use printshellcode -e <filename>

/*printshellcode.c*/

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
/*Print message function*/
static void croak(const char *msg){
    fprintf(stderr, "%s\n", msg);
    fflush(stderr);
}

/*Usage funcion*/
static void usage(const char *prgnam){
    fprintf(stderr, "\nExecute code : %s -e \n", prgnam);
    fflush(stderr);
    exit(1);
}

/*Signal error and bail out*/
 static void barf(const char *msg){
    perror(msg);
    exit(1);
}

/*main*/
int main(int argc, char **argv){

    FILE	*fp;
    void	*code;
    int		i,l,arg;
    int		m=15; /* max number of bytes on a line*/

    struct stat sbuf;
    long	flen; /*assume files are &lt; 2**32*/
    void	(*fptr)(void);

    if(argc &lt; 3) usage(argv[0]);
    if(stat(argv[2], &amp;sbuf)) barf(&quot;failed to stat file&quot;);
    flen = (long) sbuf.st_size;
    if(!(code = malloc(flen))) barf(&quot;failed to grab enough memory&quot;);
    if(!(fp = fopen(argv[2], &quot;rb&quot;))) barf(&quot;failed to open file&quot;);
    if(fclose(fp)) barf(&quot;failed to close file&quot;);

    while ((arg = getopt (argc, argv, &quot;e:p:&quot;)) != 1){
      switch(arg){
        case 'e':
          croak(&quot;Calling code ...&quot;);
          fptr = (void (*)(void)) code;
          (*fptr)();
          break;
        case 'p':
          printf(&quot;\n/* The following shellcode is %d bytes long: */\n&quot;,flen);
          printf(&quot;\nchar shellcode[] = \n&quot;);
          l = m;
          for(i = 0; i= m){
              if(i) printf("\"\n");
              printf( "\t\"");
              l = 0;
            }
            ++l;
            printf("\\x%02x", ((unsigned char *)code)[i]);
          }
          printf("\";\n\n\n");
          break;

        default:
          usage(argv[0]);
      }
    }
    return 0;
}

unmask – python profiling tool

In one of the mailing lists I’m on, this cool little python-based profiling tool was posted.  Here is the README.

This is version 1.0 of Unmask – a python script that attempts to unmask anonymous text by matching its statistical properties against someone else’s text with a known identity.

Other uses include determining “area of origin”,gender,age, occupation, sexual orientation, etc from text’s statistical properties. Any decision YOU can make against an unknown author, Unmask will also make. Of course, it may be less or more accurate than your determination.

You should probably fiddle with it as you go, to make it work on whatever sample set you have, before using it in the wild.

You can download it from http://www.immunitysec.com/downloads/unmask1.0.tar.gz.

Looking at textstats.py, it profiles based on words per sentence, types of punctuation statistics, and what types of words are used.

Pretty simple to use.  I collected a bunch of Chuck Norris text from around (you can see it here) and added it to my “chuck norris profile”.

Do this by

unmask.py -s chuck -f /path/chuck1.txt
unmask.py -s chuck -f /fath/chuck2.txt

Now, compare it with the benchmark Chuck Norris text that’s here.  This is also known Chuck Norris text.

./unmask.py -i -f ./unknown.txt
Comparing against chuck.pkl
Compared to store/chuck.pkl with match value of: 92.0
Matched closest with matchfile store/chuck.pkl:
Identification information – file: store/chuck.pkl matchvalue:92.0

not bad.  92 percent.

Now, I compare Chuck Norris with some Jesus quotes, to see if he is likely to be the second coming of Jesus.  I compared it with Mathew5:43-47

Comparing against chuck.pkl
Compared to store/chuck.pkl with match value of: 43.0
Matched closest with matchfile store/chuck.pkl:
Identification information – file: store/chuck.pkl matchvalue:43.0

Hmmm, I guess there are some flaws with the program or at least my small sample size.  I’m sure if we would have had a big enough sample, we could have verified Chuck was the second coming of Christ.  I guess I’ll save that for next time.

To use it, simple “store” text (with -s bob -f file.txt). Then just compare your unknown file to that particular store, or use -i to compare it to all stores. Make up a store of all male and all female text and then compare some random weblog, just for kicks.

websitebaker modules

Here are two modules I wrote for website baker. One allows you to sort
news arbitrarily, the other allows you to post multiple groups.

Writing these is how I wiped out this very website :) I didn’t have the installer quite right at the time. If you’re installing this, back things up just in case. But they really shouldn’t break anything. I swear.


anews.zip

gnewswrapper.zip

Here is a screenshot of anews. It allows you to sort news posts by title, date, reverstitle, or reversedate. Plus everything else the news module does, as it is just an extension of that.

Here is a screenshot of gnewswrapper. It allows you to post stuff by section from arbitrary groups.

From the readme:

Although the news module is extremely versitile, it lacks an easy way to post products or data items. For example:

-if you have a website that lists various types of faculty
-if you have a page that lists your various types of products
-if you have a page that lists courses for the current term

The news module can almost handle many of these problems. However, there are several shortcomings when the news module is ued for this purpose.

1. Although entries can be reordered, they are ordered by date. It can be a pain to click the up or down arrows until you get an order tham makes sense. With products, it might be better to have the entries ordered by price, for example. For faculty it would most likely be by their name.
2. Multiple groups, and only the groups selected cannot be easily specified. See the example below.

The group wrapper and anews modules provide a solution to this problem.

Example Usage
———-
Problem: I have hundreds of faculty, council members, and staff I want to specify at various points on the webpage. I have a CS page where I want to list the CS faculty. Elsewhere on the website, I have a University Contact page where I want to list everyone.

Solution:

-Create a single anews page that stores all people. Create different groups for CS Faculty, Council Members, etc. Make this page hidden.
-Sort it as desired, probably by name
-Create a group wrapper page and add the groups that you want displayed.

Todo
———–
It’s definitely conceivable of a time where this is insufficient.

-if you want to show items, but not necessarily the whole group
-if you want to show items in an order not specified

It should be pretty easy to extend the module to include these cases

————
These modules were written by Rich Lundeen

ssh-keygen -R

This is the correct way to remove old public keys from your known_hosts file.

There are times when public keys change for legitimate reasons.  Like when you get a new operating system installed or something.

In the past, I’ve just edited .ssh/known_hosts and deleted the entries (there is normally at least two, one for the IP and one for the host name).  This can be a bit hard because these entries aren’t really labeled clearly.

A better way is to:

ssh -R hostname
ssh -R IP
Follow

Get every new post delivered to your Inbox.