Aug 19

Reapplying the Decal: The surviving stumble to victory!

Tag: Code, ProgrammingAdam Wright @ 3:24 pm

Well, the total of received answers to the questions in the last part was 2 which, whilst somewhat less than I hoped, just makes it more of an achievement to those that tried. I’m sure lots of you are sitting at home using your solutions as some form of abstract modern art, rather than wasting them on this site, and you’re right to do so!

Ahem. Let’s see what we got.

Bonus question 1 - What changes would you make to print “Hello Hello”?

This one isn’t too great a leap from what we did in the article – rather than call both our functions in succession, we’ll call the same one twice. The only minor roadblock is working out the offset to the function, which is 013 (extra credit if you just read it from the original source!). Hence the change you wanted (using the original “helloWorld.exe”) was to change byte 0409 to “13”.

Bonus question 2 - What changes would you make to print “Hello Decal”?

Another short intuitive hop, and one for the adventurous. We reason that if we can change the code, why can’t we change the data? Indeed, “Decal” has exactly the same number of letters as “World”, so one can just use the editor to replace the “World” in the data section (address 0838) with “Decal” and voila – success!

Bonus question 3 - We know the printing functions were generated from an object in our source C++. Which of the 3 blocks in the given assembly do you think belonged to that object originally?

The 3 given blocks were basically identified as being “The start of the big list”, “Print Hello function” and “Print World Function”. From our past discussion we know that objects “know about” one single concept – in our case, the concept of printing “Hello World”. As such, it’s unlikely that the object contained the original code that makes up the whole big list, and as such the last 2 of the 3 functions are the best candidates for being part of the object. End result, the functions beginning at addresses “00401020” and “00401040” are the right answer.

Anyone who deduced that, full marks! Anyone who read up to Q5 then used that information, also full marks (plus a nod for having excellent exam technique)!

Bonus question 4 - …Use the nop instruction to stop the program from waiting for enter before exiting, and explain what you did.

More deductive reasoning, the staple of the sport. We know the code prints “Hello”, then prints “World” before finally waiting for a keystroke. We can see in the big list that the call to print “Hello” is followed by the call to print “World” – and both are followed by another call that we didn’t discuss! This being the last call in the program, we can guess with good accuracy that it’s this function performing the wait.

Taking nop, we replace all the bytes of the call and the address it’s calling with the nop instruction code (starting at 040d, replace 5 bytes with “90”) and run the result. Did you see that? No more waiting! Fantastic!

Advanced bonus question 5 - …Produce a single C++ file that will compile to the given “helloWorld.exe” program.

Well, I can’t do too much explaining on this one – you’d have to have a solid understanding of C++ to even try it. The overall concept is that one sets up some source code using the hints in question 5 and populates it with the simplest code that performs the job. Then, by analysing the original “helloWorld.exe” assembly, you alter your code to use the external objects and functions that I used. Finally, a combination of binary comparison and detailed examination of both assembly dumps can be used to “tweak” your code to match.

The winner by a country mile is Portaren, who’s question 5 answer even caught the curve ball of a 32 byte buffer when a 1 byte would have been more logical. Ignoring formatting and minor (basically stylistic) differences, his code is so perfectly identical as to warrant full marks. Portaren, leave a comment or drop me an email if you want to pick your prize! An honourable mention also goes to “Long Duk Bill” for being the only other person to submit a solution. Everyone else who didn’t send anything or who’s just curious can now download the original project files and source from here (GPG signature file here). I’ve bundled in the compiled libctiny I used, but you can make your own from the original sources at this site.

Before we finish this series, I’d like to thank everyone for playing – despite growing more complex in nature, I hope what we went through was instructive and interesting. I’d love to have your comments on the style in general as well as what could be improved as I’d imagine I’ll write at least one more Decal focused article. Whilst I have the time, I also plan to start a series on the basic reasons for the existence of numbers (take that, newly increased visitor count!), as well as finishing my previous run on software design at some point.

Vade in pace,

Adam Wright (as Asriel)

3 Responses to “Reapplying the Decal: The surviving stumble to victory!”

  1. Colin_Claytor@Frostfell says:

    I was going to become a programmer when I first went to college but that ended up not happening. Your articles only reinforce my decision not to become one as it all seems very complex. :) heh. Perhaps that’s why you didn’t have a lot of submissions of answers to the questions.

    Just want to say thanks for the updates on Decal and keep up the good work. :)

  2. Mike Smitson says:

    // Hello_World_CPP.cpp : main project file.

    #include “stdafx.h”

    using namespace System;

    int main(array ^)
    {
    Console::WriteLine(L”Hello World”);
    return 0;
    }

  3. Mike Smitson says:

    Submitted the “Hello World”

    Keep up the good work…you are not forgotten…I know a lot of people will read this and go ahhhhhhh!
    Then they will not comment. Don’t fret over low responses…it takes a person into programming to understand this!

Leave a Reply