Please create an account to participate in the Slashdot moderation system

 



Forgot your password?
typodupeerror
Programming

Journal: Adventures in modern programming

Journal by Earthquake Retrofit

I learned to program in BASIC on a TRS-80 model 1 level 1. By the time I got level 2 BASIC I was already exploring machine language. I actually hand assembled some stuff. Later I learned PL/I, Pascal, assembly in IBM 370 (got an A) and, god help me, COBOL at university. But that was all thirty years ago and only had a Commodore well into the 1990s.

I recently watched the lectures at the M.I.T. website for the introductory C++ course. The professor was quite entertaining but wasn't too useful on a practical scale. No doubt the labs are much more informative. But it got me inspired to learn a modern language. The Microsoft APIs were enough to chase me away from assembly for a while. And got me to install Linux.

I'm not completely clueless and I've read all about Java since it started and OOP. And I never quite got it. Lots and lot of tutorials exist on the web, some of which are worse than useless for a beginner. But this time I wasn't going to be discouraged. I got going and decided I would make a spaceship. Threads, I think. Now that's something I can have fun with.

At "http://www.linuxselfhelp.com/HOWTO/C++Programming-HOWTO-18.htm", I found this mess:

class Thread
{
      public:
            Thread();
            int Start(void * arg);
      protected:
            int Run(void * arg);
            static void * EntryPoint(void*);
            virtual void Setup();
            virtual void Execute(void*);
            void * Arg() const {return Arg_;}
            void Arg(void* a){Arg_ = a;}
      private:
            THREADID ThreadId_;
            void * Arg_;
};
Thread::Thread() {}
int Thread::Start(void * arg)
{
      Arg(arg); // store user data
      int code = thread_create(Thread::EntryPoint, this, & ThreadId_);
      return code;
}
int Thread::Run(void * arg)
{
      Setup();
      Execute( arg );
} /*static */
void * Thread::EntryPoint(void * pthis)
{
      Thread * pt = (Thread*)pthis;
      pthis->Run( Arg() );
}
virtual void Thread::Setup()
{ // Do any setup here
}
virtual void Thread::Execute(void* arg)
{ // Your code goes here
}

Forty three lines. All this to implement a thread? Oh, well look at all the difficulties you have to overcome:

"The create a thread, you must specify a function that will become the entry point for the thread. At the operating system level, this is a normal function. We have to do a few tricks to wrap a C++ class around it (*) because the entry function cannot be a normal member function of a class. However, it can be a static member function of a class. This is what we will use as the entry point. There is a gotcha here though. Static member functions do not have access to the this pointer of a C++ object. They can only access static data. Fortunately, there is way to do it. Thread entry point functions take a void * as a parameter so that the caller can typecast any data and pass in to the thread. We will use this to pass this to the static function. The static function will then typecast the void * and use it to call a non static member function."

* He doesn't say why on Earth I would want to...

A FEW tricks he says and a gotcha. And still does nothing yet. Now look at this thread declaration:

void*
shield_running(void* data) {

        float fuel_usage = .0195; //rate of use kilos per minute

      while (Shield.power_on == true){
        Shield.min_of_operation = (Shield.min_of_operation + (1/60));
        Cargo.fuel = (Cargo.fuel - fuel_usage);
        Air.dust = (Air.dust + .0001);
        if (Shield.boost_on == true) {Cargo.fuel = (Cargo.fuel - fuel_usage);};
        sleep(1); };
        pthread_exit(NULL);
                      };

which is started by the following:

if (choice == "so") {Shield.power_on = true;
        choice = "0";
        thr_id = pthread_create(&p_thread, NULL, shield_running, (void*)&g);};

Only seventeen lines, it actually does something, is very easy to understand, was easy to adapt to other systems like my oxygen generator, and if I had 100 shields I could start a hundred threads. My teachers at SIU would not have liked the lack of comments, but C++ is almost self-documenting. And if this is actually true: "The call to pthread_exit() Causes the current thread to exit and free any thread-specific resources it is taking." then there should be no problem with memory leaks which I know jack about.

Both are written in the same C++. That's why I decided to learn C++. I could do it my way. I get the first example, Now. But I LEARNED from:

http://users.actcom.co.il/~choo/lupg/tutorials/multi-thread/multi-thread.html#definition
This one has clearly explained concepts and example programs that ACTUALLY COMPILE!

'Public' and 'private' and 'restricted'? Global and local are good enough for the likes of me. But I'm not totally close-minded. I suspect that a graphic user interface, which every modern spaceship should have, may actually require the use of classes. If so, like the way Republicans say they voted for McCain, I'll hold my nose and do it.

Now if only I could find a simple example of a C++ program with a simple GUI that ACTUALLY COMPILES on Kdevelop, I might have enough fun for another thirty years. Tonight... make that tomorrow, I'm trying out QT designer.
 

Programming

Journal: Buffer overflows explored

Journal by Earthquake Retrofit
As a beginning assembly language programmer, I've been having trouble getting my head around buffer overflows as a security vulnerability. The popular media has many lurid stories containing few details and the detailed descriptions often mean nothing to me. So I decided to design a purposefully insecure program as a thought experiment.

I make a web page with a box labeled "Type your 16 charecter password to get the file." When the user presses ENTER whatever he typed is sent to my program without any check for the proper length. I have read that any client-side bounds checking could be disabled. Hole number one. I would leave the check in anyway.

A 16 byte variable will hold the user's password and is defined in memory and initilized to -1 just before the beginning of the code for the first procedure. So anything written starting at that address that's longer that 16 bytes overwrites what comes after in the program. Hole number two? But this is crazy, variables are defined all over the place.

Now, the first procedure displays the file. Let's say that routine is 100 bytes long. The second procedure checks for a valid password and returns zero in a register if the password is valid, unchanged if not.

A third procedure, trusting the client-side checking, if there was any, blindly writes whatever it gets from the user to memory starting at the address of the password variable, so anything bigger than 16 bytes begins to overwrite the code that follows. Overflow. Hole number three.

So if an attacker types in any 16 characters and then the exact 100 bytes of the hex code of the first procedure, which can't be changed if the attacker wants the file, then replaces the guts of the second procedure, which checks the password, with hex code that only has to set the register to zero and return from the procedure. Exploit! As long as the modified code is running, any subsequent user will also have access to the file as long as their password is 16 charecters or less.

But an attacker would have to know the exact 100 bytes of the first procedure to get the file. Get it wrong, and the program crashes or behaves unpredictably which I have no idea how to exploit. But it is a denial of service. Get it right and subsequent users could also easily crash it. But unless I publish the source or executable code how would anyone know? It's only running on my machine. Security by obscurity?

This does seem to meet the description 'allows attacker to execute arbritary code.' If the attacker isn't interested in the file, he or she could inject code to take over my box IF the running program has administrator privileges. That would be hole number 4.

All of these holes, except maybe number one and two, seem to be easily prevented, so why do buffer overflows occur so often? This all seems obvious to me as a beginner, but there's a lot I don't know yet. For instance, 19,000 windows APIs.

Steve

Programming

Journal: Installing an editor/assembler 1

Journal by Earthquake Retrofit

Well, it had warned me, but holy shit the anti-virus went off like I've never seen before. So I choose 'send file(s) to virus vault' and worried, but perhaps feeling brave, (or crazy see below) keep going. Weird console window but it seems to be assembling and linking libraries, just like it said. Run the editor, File, Open... SIRENS warning warning Trojan. "WTF, just from looking at a directory?" Alright, this isn't working. I checked the add-install list, nothing, but I already read that it would be unzipped not 'installed'. I deleted it all. Back to the website. The guy at the forum says "It's not my fault, It's not my fault! huristics don't understand assembly level programs because we're crazy."

"Okay," I think, "that makes sense." And the free AV I'm using is one of the two implicated. I disable my internet connection and I'm not turning off my huristics so I'll just choose ignore. I run the installer, same as before, ignore ignore. So far so good. I run the editor, fine. File, Open, warning! warning! No, I'm gonna get tired of this. So, back to the AV. Turn off huristics. Run the editor. No effect, same as before. But I happened to noticed the 'exclude path' choice on the AV advanced menu and that finally worked.

File, Open, example1.asm. "Oooo, pretty."

So my question is, just how crazy do assembly level programmers have to be? Steve

If mathematically you end up with the wrong answer, try multiplying by the page number.

Working...