Archive

Archive for January, 2009

Bolt Browser Review

January 19th, 2009 2 comments

When I first heard about Bolt Browser for J2ME mobile phones, I couldn’t wait to try it out and see how it compares to Opera Mini 4.2.

I’ve used WebKit based browsers such as TeaShark and the native Nokia S60 browser before and as far as rendering speed is concerned, these browsers take as much as 5 times the amount of time Opera Mini takes to render a page.

So it was interesting to test Bolt against Opera Mini and Webkit browsers.

Startup:

Bolt’s installation procedure is similar to Opera Mini’s but it takes a lot more time to start than Opera Mini.
Here’s how the startup screens look like:

opera_loadingbolt_loading Loading Screens

opera_startscreen bolt_startscreen Start Screens

Both start-screens are alike, except that Opera Mini displays History, Bookmarks and Feeds vertically while Bolt displays it horizontally.

Rendering Performance:

Bolt’s Rendering accuracy is really good, however it does mess up a few images i.e. the colour of the images is a little different from the original.

Speed-wise, Bolt is a lot faster than Webkit based browsers but is slower than Opera Mini. Although Bitstream claims that it is faster than Opera Mini, I didn’t think so. It is fast, but not as fast as Opera Mini.

It’s interesting to note that Bolt works flawlessly with Bloglines while Opera Mini and Webkit browsers don’t work.

However, on many pages Bolt throws up errors almost every time.

bolt_error Although errors like this can be resolved with a refresh, I encountered another error that announced that Bolt had an unrecoverable error and sent an error log to their server. I couldn’t take a screenshot as I couldn’t reproduce it again.

Data Reduction:

Although Bitstream claims that its data reduction ratio is 23:1, there’s really no way of verifying this as Bolt has no option to view web-page information. Opera Mini’s Page Information looks like this:

opera_pageinfo1 opera_pageinfo2

Features:

To be honest, Bolt’s features are basic at best. The only feature that is unique to Bolt and sets itself apart from other browsers (including Opera Mini) is the Split-Screen feature.

In Split-screen mode the screen is horizontally divided into half. The top half has the zoomed-out view of a page while the bottom-half shows a full-zoomed area of the page around the cursor and it looks like this:

bolt_splitscreen

Other than this, Bolt doesn’t have much to brag out. Bolt’s Bookmark and RSS Feed Managers are similar to other browsers.

If  the current webpage has a number somewhere, Bolt detects it and allows you to either call or send an SMS to that number. Opera Mini also detects numbers but only allows the user to call the number. Both browsers are terrible at recognizing phone numbers though, phone models (such as P230, N70, N95), addresses and version numbers are confused as telephone numbers.
Opera Mini on the other hand has Opera Link for bookmark synchronization, is skinnable, allows pages to be saved on phone or memory card, supports HTTP Authentication (bolt doesn’t) and supports multiple search-engines and even custom Search Strings like this:

opera_searchengines fdsf opera_customsearch

Customization:

Again, a no show. There’s hardly any options to choose from.
bolt_settingsbolt_pagemenu
bolt_mag bolt_https

That’s it. There are no more options in Bolt. Compare this with Opera Mini’s options:

opera_settings1 opera_settings2 opera_pagemenu

Final Word:

For a browser in its beta stage, Bolt is pretty good and I expect the final version to be a little faster and more feature-rich. Even in its beta stage it’s better than most Webkit based browsers. However, it lacks many basic features (such as tabbed browsing, copy-pasting and page saves) and if the final version doesn’t include any new features, then there’s absolutely no way Bolt can be an Opera Mini killer. Bolt has the potential, but only time will tell.

The Windows Green-Screen

January 17th, 2009 6 comments

I wanted to post this a few years back but I just didn’t have the time.

This is something really interesting and it seems that nobody else has come across this little secret.

Many members from dreamincode.net Forums asked me how I could make my signature show videos running in the background and I’ve finally found time to explain how.

This is how my Forum Signature looks like (or looked like when I was writing this post) :b2c_sig

To see how this works, follow these steps:

  1. Open your favourite media player and play any video file.
  2. Ensure that the media player window is covering the image above.
  3. Now, minimize the media player.
  4. You should now see a portion of the video being played on the image as if the image itself were a media player.

Awesome, isn’t it?

I figured this out while I was experimenting with an application of mine which tried to modify Media Player Classic on-the-fly.

It seems that in Windows XP (might also be true for other windows OSes and other OSes), Video files can only be displayed on a portion of the screen that has a particular colour. The video can only be displayed on a portion of the screen which is currently displaying a specific colour.

That specific colour is RGB(16,0,16).

Try it out for yourself. Create an image with a background colour of RGB(16,0,16) like this:b2c_test_screen

Now play any video over this image and minimize the video player. The video should now be visible on the image.

My guess as to why this works is that Windows (or other OSes) needs to be able to figure out where a video should be displayed when a media player requests for playback. According to me, this has been intentionally included in the video playback design.

If the media player just provided co-ordinates of a rectangle to the OS for displaying the video, that would mean that if any other application was placed on top of the media player window, the video would be displayed over the application’s interface which would not allow the user to see the application’s user interface (forms, controls etc.)

Here’s what I think they did to fix the problem.

The principle behind this design could have been that “if a video could be displayed only within a rectangle that displayed only a specific colour, no overlapping application would be affected.

But which colour would be best suitable for this purpose? Black is the first colour that comes to my mind for obvious reasons but black is a common colour and is used frequently in desktop wallpapers or in user interface elements.

Hence they chose a colour that’s technically not black but would look just like black and hence they must have come up with the colour RGB(16,0,16)

My reasoning probably isn’t correct but I’m pretty sure that the real reason is based somewhere along the lines.

I just find it ironic that something that behaves just like a green screen doesn’t even have a hint of green in its colour code (its 16,0,16 in RGB) ;)

As I’m still not sure if this works on other operating systems, I’d appreciate it if you could test this on your operating system and post the result as a comment to this post. Thanks.

Fixing a CD in 3 easy steps

January 17th, 2009 3 comments

A friend gave me his CD which had broken into two pieces and asked if I could fix it.

cd_before

Looking at it I knew there was no way I could recover all the files correctly, but there was a possibility that some files could be recovered. So I took up the challenge.

The first thing that I wanted to do was to attach the CD using Pidilite’s FeviQuick but I didn’t have any so I used FeviCol instead to attach the two pieces together.

step1

There were way too many scratches and the portion near the crack had vanished so I wasn’t too optimistic about the result. But I had way too much time on my hands so I thought I’d go all the way just to see what happens.

After an hour or two, the glue had hardened but the CD would still bend when lifted. I then used cellotape to ensure that the CD remained in one piece.

step2

After the cellotape fix, I realized that I had spilt some of the Fevicol on the CD layer.

step3_before

I used a combination of cologne and my mom’s nail polish remover to remove the glue and it even managed to remove a few scratches.

step3_after

That’s it. The CD was firm, relatively clean and seemed ready for the Acid Test  so I inserted it in my laptop’s CD drive.

step4

Obviously with the amount of damage the disc had taken there was no way Windows would even detect it as a CD.

I used some of the free tools from here and I managed to recover a few text files, pictures and portions of a video.

You’ll probably have more luck with your recovery process if your CDs are in better condition. ;)

Categories: Do It Yourself Tags:

Visual Basic 6 Internal Event Handling

January 16th, 2009 1 comment

VB6 calls control events in a very specific way. It’s impressive but the design of event handling results in losing a certain number of guaranteed bytes per control used. By losing bytes, I am referring to the addition of redundant bytes in the executable code.

I studied the entire structure with Disassemblers and debuggers and found out that the total number of redundant bytes is  governed by the following formula:

Total Redundant Bytes = SUMMATION OF (4 x (Number_Of_Events + 6 – Events_Used) ) FROM 1 TO N

where:
N = Total Number of Controls Used
Number_Of_Events = Total Number Events Supported by a Control (Different for each control)
Events_Used = Number of Events Used for each control.

So Imagine a simple form having two text boxes and 1 command button for a simple login box, considering that only the following events are used:
Form_Load()
Command1_Click()

The Total number of Redundant Bytes is:
(4*(31+6-1)) + 2*(4*(24+6)) + (4*(17+6-1)) = 472
1 FORM + 2 TEXT BOXES + 1 CMD BTN

That’s 472 unnecessary bytes just for a simple login box using absolutely no user-written code.

Many people refer to VB6 as Visual Bloatware, and you now know why ;)

Categories: Code Internals Tags: , ,

Does Minesweeper Cheat?

January 16th, 2009 4 comments

I’ve come across a few people who believe that minesweeper lays down only half the number of bombs and only adds the other half on the board as the game progresses.

I debugged the game myself and have found that it is completely false. However, the game ensures that you don’t click a bomb on the first click. Hence, if the first click is a bomb, it is removed from the grid and placed at the first empty location from the coordinate (0,0) i.e. the top-left location.

Hence, if you clicked on (3,2) which originally had a bomb, it would be removed from (3,2) and placed at (0,0) if that location were empty.

This can also be verified without using a debugger. Use the xyzzy cheat to enable the white pixel at the top-left corner of the screen. Then, find a location which contains a bomb (ie. black pixel at top-left corner of the screen) but don’t click it. Now, move your cursor to the top-left corner of the screen and check if it has a bomb.

Now click on the previous location which had a bomb and you’ll notice that there isn’t a bomb once you click it. Then move your cursor to the top-left corner of the board and you’ll notice that the bomb has been shifted to the top-left location.

Minesweeper cheats FOR you and not against you to ensure that you can start the game without clicking a bomb everytime.

Categories: Myths Tags: , ,

Another Application of One-way Hash Functions

January 9th, 2009 No comments

We’ve all heard of one-way Hash Functions sometime or the other.
Most of us have heard about them from books.
An Algorithm’s explanation is usually followed by its applications and most books mention only one major application (in security) ie. implementing password checks and storing them in a database.

I used to wonder:”That’s it? One Application in Security?”, and searching on the internet (and some more books) didn’t help either.

Luckily, I’ve finally found my answers. Now, I’m able to appreciate one-way Hash functions a lot more because I’ve seen it in action. If I had read this application in a book I’m sure that I wouldn’t have realized its importance.

A few days ago, Nokia Corporation issued a notice to all customers that some of its BL-5C Model Batteries had some manufacturing defects which could cause it to explode. It asked customers to check if their batteries were manufactured between December 2005 and November 2006 and if so, get the battery replaced for free.

Nokia also allowed its customers to type in their 26 Character Battery Code on their website (www.nokia.com/batteryreplacement) to see if their battery was faulty or not.

I decided to check the script which finds out when the battery was manufactured. I thought that by looking at the source code, I could figure out exactly which batteries were faulty.

This is what the script looks like:

function rcrcheck_serial()
{
   var isgood=false;
   var serial=document.enterserial.serial.value;
   var a=”;
   var b=”;
   var c=”;
   if(serial.length<26)
   {
      alert(”The identification number is incorrect. Please check that you have entered the full 26 characters of the battery identification number.”);
      return false;
   }
   if(serial.length>26)
   {
      alert(”The identification number is incorrect. Please check that you have entered the full 26 characters of the battery identification number.”);
      return false;
   }
   a=md5(serial.substr(7,6));
   b=md5(serial.substr(13,1));
   c=md5(serial.substr(14,3));

   if(a!=”ea4a302b5cbd017871ec94fd6ae189b5?
&&amp;amp;amp;amp; a!=”1f098214896cc40cfabc3b2403a65b75? //###
&& a!=”fd06cd296b4bf634d85e26884565aa6c”) { //###
window.location=”rcrb2.html”;
return false;
}if(b==”8d9c307cb7f3c4a32822a51922d1ceaa” b==”7b8b965ad4bca0e41ab51de7b31363a1?) { //###
if(c==”84eb13cfed01764d9c401219faa56d53?){return true;} //###
if(c==”d2490f048dc3b77a457e3e450ab4eb38?){return true;} //###
if(c==”441954d29ad2a375cef8ea524a2c7e73?){return true;} //###
if(c==”0e51011a4c4891e5c01c12d85c4dcaa7?){return true;} //###
if(c==”af032fbcb07ffc7bd2569d86ae4ce1f5?){return true;} //###
if(c==”73f7634ab3f381fb40995f93740b3f8a”){return true;} //###
if(c==”738cccd4fda172441f216712a488dca6?){return true;} //###
if(c==”f803dfeb3583d5099a58a7478f28bd75?){return true;} //###
if(c==”7f5144f962efde75e0f7661e032166db”){return true;} //###
if(c==”8fc4c7ab4453d247e011738197b6136c”){return true;} //###

/* Some more Comparisons */

if(c==”defd40204344c9659a0a3eb4ebc125f6?){return true;} //###
if(c==”c4de9fe96832a877668d0dced80657b8?){return true;} //###
if(c==”2c62105ee18ecd5f0ee37bc8c35718eb”){return true;} //###
if(c==”3994f23bfb2b89994bd6e828977b42ae”){return true;} //###
if(c==”28fd0fbd334515deb8a8291b71941c9e”){return true;} //###
if(c==”9ac05befca7d6499e3abec9bdfef2b68?){return true;} //###
if(c==”1732cb437260c60a0744aea8aedfa331?){return true;} //###
if(c==”e1eee5e2b42d45443cdc82db1a3bc465?){return true;} //###
if(c==”7d06a9cf10f2e9e47e77d6c6cfaa7f54?){return true;} //###
if(c==”2618045a3a5fc883e65b6bec2fcac3c8?){return true;} //###
if(c==”2421fcb1263b9530df88f7f002e78ea5?){return true;} //###
if(c==”fccb60fb512d13df5083790d64c4d5dd”){return true;} //###
if(c==”15d4e891d784977cacbfcbb00c48f133?){return true;} //###
if(c==”c203d8a151612acf12457e4d67635a95?){return true;} //###
if(c==”13f3cf8c531952d72e5847c4183e6910?){return true;} //###
if(c==”550a141f12de6341fba65b0ad0433500?){return true;} //###
if(c==”67f7fb873eaf29526a11a9b7ac33bfac”){return true;} //###
if(c==”1a5b1e4daae265b790965a275b53ae50?){return true;} //###
if(c==”9a96876e2f8f3dc4f3cf45f02c61c0c1?){return true;} //###
if(c==”941e1aaaba585b952b62c14a3a175a61?){return true;} //###
if(c==”9431c87f273e507e6040fcb07dcb4509?){return true;} //###
if(c==”49ae49a23f67c759bf4fc791ba842aa2?){return true;} //###
if(c==”e44fea3bec53bcea3b7513ccef5857ac”){return true;} //###
if(c==”821fa74b50ba3f7cba1e6c53e8fa6845?){return true;} //###
if(c==”250cf8b51c773f3f8dc8b4be867a9a02?){return true;} //###
if(c==”42998cf32d552343bc8e460416382dca”){return true;} //###
if(c==”0353ab4cbed5beae847a7ff6e220b5cf”){return true;} //###
if(c==”51d92be1c60d1db1d2e5e7a07da55b26?){return true;} //###
if(c==”428fca9bc1921c25c5121f9da7815cde”){return true;} //###
if(c==”f1b6f2857fb6d44dd73c7041e0aa0f19?){return true;} //###
if(c==”68ce199ec2c5517597ce0a4d89620f55?){return true;} //###
if(c==”e836d813fd184325132fca8edcdfb40e”){return true;} //###
if(c==”ab817c9349cf9c4f6877e1894a1faa00?){return true;} //###
if(c==”8e6b42f1644ecb1327dc03ab345e618b”){return true;} //###
if(c==”ef575e8837d065a1683c022d2077d342?){return true;} //###
if(c==”2050e03ca119580f74cca14cc6e97462?){return true;} //###
if(c==”25ddc0f8c9d3e22e03d3076f98d83cb2?){return true;} //###
if(c==”5ef0b4eba35ab2d6180b0bca7e46b6f9?){return true;} //###
if(c==”598b3e71ec378bd83e0a727608b5db01?){return true;} //###
if(c==”74071a673307ca7459bcf75fbd024e09?){return true;} //###
}
if(b==”69691c7bdcc3ce6d5d8a1361f22d04ac” b==”6f8f57715090da2632453988d9a1501b”)
{ //###
   if(c==”2bb232c0b13c774965ef8558f0fbd615?) {return true;} //###
   if(c==”ba2fd310dcaa8781a9a652a31baf3c68?) {return true;} //###
   if(c==”69421f032498c97020180038fddb8e24?) {return true;} //###
   if(c==”85422afb467e9456013a2a51d4dff702?) {return true;} //###
   if(c==”13f320e7b5ead1024ac95c3b208610db”) {return true;} //###
}
window.location=”rcrb2.html”;
return false;
}

This code is awesome because, even after reading the source code, nobody can figure out which models are faulty. At the most what we can understand is that Battery Information (Date of Manufacture, Location of Manufacture) is present between the 8th and 17th characters. The characters between 18 and 26th positions could hold the amount of batteries manufactured by the factory before the current unit. We also know that the battery is faulty for some 334 combinations of characters between the 14th and 17th positions. But having this knowledge is futile.

Hence by using a one-way Hash Algorithm (MD5 in this case), we can hide such information (factory codes of factories which manufactured the faulty batteries) even in the source code. This way we can protect such vital information from being stolen by anyone even if he has access to the complete source code, and this according to me is one of the most brilliant applications of One-way Hash functions.

Categories: Programming Tags: ,

String Termination in C/C++

January 9th, 2009 No comments

This is a typical assignment given to students who are learning C/C++.
“Write a function that copies the contents of one string into another.”
Note that in this example a string is referred to as a character array.

Some people come up with code similar to this one:

void copy(char [],char []);

int main()
{
   char s1[10],s2[10];
   printf(”Enter String 1:”);
   gets(s1);
   copy(s1,s2);
   printf(”nThe copied string is: “);
   puts(s2);
   return 0;
}

void copy(char x[],char y[])
{
   int i=0;
   while(x[i])
   {
      y[i]=x[i];
      i++;
   }
}

Can you notice that something is missing in the copy() function? Yes, the null termination character was not appended at the end of the new string. I corrected a friend of mine who the same mistake and he asked me why the code works for other strings as well such as “Sanch”.

Luckily, we were near a computer so I could demonstrate my examples straight away to convince him.

Observe the declaration of this character array:

char name[10]=”Sanchit”;

Internally, this String is stored like this:
S,a,n,c,h,i,t,,,

Yes, if the string initial declaration is less than the size provided in the square brackets, the rest of the elements are filled with zeros. This is applicable for arrays of any data type.

Since the ASCII Value of is 0, I can represent my array like this again,

S,a,n,c,h,i,t,0×0,0×0,0×0

Does this ring any bells?

If you create another array of the same size (here: 10) and copy this string to it using the code given above, the rest of the elements after the String are already . So there is no need to the character as C would know where the string terminates.

But what if the String is larger? Assuming “Sanchit Karve” is stored in the same Array, it will look like this:
S,a,n,c,h,i,t, <space> ,K,a,r,v,e, , , …

If you notice, that inspite of the string being larger than the array size, it is stored completely after occupying the space after the array. Since, now the space outside the array has been accessed, the data out there is not zero. Instead they contain garbage values. So, for such situations, we need to append the character at the end of the string, so that C can figure where the string ends. Otherwise, C will output all bytes till a zero is encountered.

So, appending the character is not required if we assume that the string length is lesser the array size. However, we should also ensure that we declare enough space before input larger than the allocated size because of the following reasons:

  • Unlike other Languages C/C++ do not provide Array Bound Checking features.
  • Hackers make the most of such types of errors, known as Buffer Overflow Errors, and launch Buffer Overflow Attacks where the string is inserted with shellcode (yes, in hex), and the return address of the function is overwritten to the address of the string. This results in the processor passing control to the shellcode and executing it after the function returns. But just because we append the character does not mean that Buffer Overflow Errors don’t occur. But it’s done just as a safety measure so that the program can run without faults.
Categories: Programming Tags: ,

Passing 2D Arrays to functions

January 9th, 2009 No comments

Passing 2D arrays without bounds is a common error people make.
Some people assume that if this works:

void someFunc(int []);

then this should should work too:

void anotherFunc(int [][]);

As normal as it may seem, it is incorrect.

For passing 2D Arrays to a function, the column element must be mentioned like this:

void func1(int [][upperSize]);

But why do we need to include the column element? If C/C++ compilers can figure out the size of a 1D array then why not for 2D?

That’s because 2D Array elements are stored consecutively as two 1D Arrays.

Have a look at this code snippet:

int main()
{
int x[][2]={1,2,3,4,5,6,7,8,9,10};
int *p,*q;
int i;
p=&x[0][0];
for(i=0;i<10;i++)
printf(”%d “,*(p+i));

printf(”nn Now using pointer q:n”);

q=&x[1][0];
for(i=0;i<10;i++)
printf(”%d “,*(q+i));

return 0;
}

Run the Program. You’ll get this as the output.
1 2 3 4 5 6 7 8 9 10

Now using pointer q:
3 4 5 6 7 8 9 10 0 4239532

Now change the number 2 in the array declaration to 5 like this:

int x[][5]={1,2,3,4,5,6,7,8,9,10};

Run the code and observe the output:
1 2 3 4 5 6 7 8 9 10

Now using pointer q:
6 7 8 9 10 0 4239532 0 4235541 1

As you can see, the output using the pointer p remains unchanged because we’re setting it to the first element of the array itself, so it iterates to every element after it.

But q is set to the first element of the 2nd row.
Now which one is the first element of the second row? It’s 6. How do we know it?
It’s because we’ve placed 5 in the column bracket to specify the bounds of each column.

So if we don’t place any value, the compiler gets confused as to how many numbers can be grouped into one column.
Hence whenever such confusion occurs, the compiler generates the error: size of the int[] is unknown or zero.

Categories: Programming Tags: ,

Reversing a String recursively

January 9th, 2009 No comments

When you’re asked to reverse a string, you’ll mostly use the strrev() function or write your own boring implementation using loops.
Ever tried it recursively?

Have a look at this:
#include <iostream>

using namespace std;

void ret_str(char* s)
{

if(*s != ”)
ret_str(s+1);

cout << *s;

}

int main()
{
ret_str(”born2c0de”);
return 0;
}

Isn’t that some neat piece of code? All we have to do is push the next character to the stack, so when the stack is popped, the characters come out in reverse order.

However this functions isn’t efficient, it’s horribly slow and sluggish and larger strings will result in overloading the stack so you’re better off using the functions which use loops internally.

Categories: Programming Tags: , ,

Consequences of Data type Range Violations

January 9th, 2009 2 comments

I’ve come across a lot of people who wonder why a number stored in a variable, if exceeds its range, turns into a weirder negative number.
To explain this phenomena they offer a conclusion without showing any evidence and this conclusion is in no way close to the truth.
Here’s what happens.

The numbers change because of the complement notation that the computer uses to store negative numbers.

And it’s not the compiler’s fault but the processor’s limitation.
This code will give negative numbers on 32-bit,16-bit and 8bit Microprocessors as each register can hold 32/16/8 bits respectively.
You won’t encounter this problem on 64-bit processors as each register can hold a maximum of 64-bits. (Actually, you will encounter the same problem since the value of INT_MAX will be a 64-bit number for a 64 bit processor….but it’ll work fine with 32-bit numbers)

Adding a Number to a maximum value set in these registers creates the problem.
Have a look at this printf statement (I’ve typecasted it for portability)

printf(”%d = %xn%d = %x”,INT_MAX,INT_MAX,(unsigned long)INT_MAX+1,(unsigned long)INT_MAX+1);

The compiler generates the following code:

push    10000000000000000000000000000000b
push    10000000000000000000000000000000b
push    1111111111111111111111111111111b
push    1111111111111111111111111111111b
push    offset aDXDX ; format
call    _printf
add     esp, 14
…
…
aDXDX  db ‘%d = %x’,0Ah
       db ‘%d = %x’,0

Now, the values in the first 2 push Instructions is the binary representation of INT_MAX (2147483647 for 32-bit systems). Note that it is comprised of only ONE’s.

When 1 is added to INT_MAX, look what happens to the next two push instructions.
This number is 2147483648 but in unsigned notation…but in signed notation it’s -2147483648 since the Most Significant Bit decides the Sign of a Number.

And since by default the compiler assumes that a variable is signed, you get the negative value.

Try the same C code after replacing %d with the %u format specifier.
You’ll notice that 2147483648 will be the output.

Remember, there’s nothing like postive or negative numbers…It’s all about interpretation. 111 (for a 3 bit architecture) could mean 7(without using MSB for sign-convention…ie. unsigned) as well as -1 (using MSB for sign ie. signed).

You might wonder why I’ve blamed the Processor and not the compiler in spite of the fact that the Compiler has precalculated the result of addition and passed it to printf.
The reason is that I’ve compiled the above code in Aggressive Optimization, so the compiler generates push instructions.
Normally the Compiler plays safe and lets the processor take care of such values by generating the following code:

mov eax, 1111111111111111111111111111111b
lea edx, [eax+1]
push edx