Another solution
[spoiler]Setting the length of a write to 0 works in this case, but let’s extrapolate this challenge to a real world case. Imagine that instead of printing a message in the console, the program is actually invoking some protection code that prevents us to reverse the program. In that case, what we really want to do is to skip the execution of that function, or deactivate the protection. As our “function” is just a write to stdout, let’s solve the challenge skipping the code instead.
This solution is a lot longer but it is way more interesting.
First thing I have to say is that this challenge is very cool. It first deobfuscate the real code that is XOR encoded at the beginning of the .text segment. Then it runs that code that, instead of showing the messages in the console, “writes” new code to write the messages in the console. After that, it deobfuscate the data segment (actually the equivalent to .rodata) with a different key and finally, it runs the generated code, the one printing the message we have to remove. As I said this is really cool stuff. Kudos to @dtm!
So, let’s get started.
Using gdb and setting a couple of break points (I will not give you all the details so you can still have some fun
you can easily deobfuscate the original code and then run it to get the final code (sure, a little bit of dynamic analysis will not hurt). The original deobfuscated code looks like this:
Dump of assembler code for function ektwwpoijwng:
0x08048071 <+0>: 90 nop
0x08048072 <+1>: 41 inc %ecx
0x08048073 <+2>: 31 ff xor %edi,%edi
0x08048075 <+4>: 31 c9 xor %ecx,%ecx
0x08048077 <+6>: 40 inc %eax
0x08048078 <+7>: c6 00 b8 movb $0xb8,(%eax)
0x0804807b <+10>: 40 inc %eax
0x0804807c <+11>: c7 00 04 00 00 00 movl $0x4,(%eax)
0x08048082 <+17>: 83 c0 04 add $0x4,%eax
0x08048085 <+20>: c6 00 bb movb $0xbb,(%eax)
0x08048088 <+23>: 40 inc %eax
0x08048089 <+24>: c7 00 01 00 00 00 movl $0x1,(%eax)
0x0804808f <+30>: 83 c0 04 add $0x4,%eax
0x08048092 <+33>: c6 00 b9 movb $0xb9,(%eax)
0x08048095 <+36>: 40 inc %eax
0x08048096 <+37>: c7 00 64 81 04 08 movl $0x8048164,(%eax)
0x0804809c <+43>: 83 c0 04 add $0x4,%eax
0x0804809f <+46>: 66 c7 00 8b 15 movw $0x158b,(%eax)
0x080480a4 <+51>: 83 c0 02 add $0x2,%eax
0x080480a7 <+54>: c7 00 70 81 04 08 movl $0x8048170,(%eax)
(...)
And, once it is executed, the final code is unveiled:
Dump of assembler code for function ektwwpoijwng:
0x08048071 <+0>: 90 nop
0x08048072 <+1>: b8 04 00 00 00 mov $0x4,%eax
0x08048077 <+6>: bb 01 00 00 00 mov $0x1,%ebx
0x0804807c <+11>: b9 64 81 04 08 mov $0x8048164,%ecx
0x08048081 <+16>: 8b 15 70 81 04 08 mov 0x8048170,%edx
0x08048087 <+22>: cd 80 int $0x80
0x08048089 <+24>: b0 04 mov $0x4,%al
0x0804808b <+26>: b9 74 81 04 08 mov $0x8048174,%ecx
0x08048090 <+31>: 8b 15 7c 81 04 08 mov 0x804817c,%edx
0x08048096 <+37>: cd 80 int $0x80
0x08048098 <+39>: bb 00 00 00 00 mov $0x0,%ebx
0x0804809d <+44>: b8 01 00 00 00 mov $0x1,%eax
0x080480a2 <+49>: cd 80 int $0x80
Now we have to work backwards. First decide what to patch in the final code, then patch the generator code to produce what we want, and finally obfuscate our patch to be able to apply it to the original file.
We have many options for the first step. I’m not sure whether the one I have chose is the best but it just works. You guys can try to beat this 
If we look at the code we can see that we need EBX set to 1 also for the second write call (the second int $0x80), I decide to hook into the mov $0x8048164,%ecx so I let the original code to set EBX for me. If we change this instruction (the mov into ecx) into a jmp to 0x08048089 then we are done. So we will have to inject a relative jump (2 bytes) at address 0x0804807c to skip the first write and continue with the second, located at 0x08048089. This leads us to the following offset for our relative jump: 0x08048089 - (0x0804807c + 2) -1 = 0x0a
So, we want jmp +0x0a at 0x0804807… that translates to opcodes eb 0a.
Fine. Now it’s time to look into the generator function. The commands that generates the instruction we want to patch are these:
0x08048092 <+33>: c6 00 b9 movb $0xb9,(%eax)
0x08048095 <+36>: 40 inc %eax
0x08048096 <+37>: c7 00 64 81 04 08 movl $0x8048164,(%eax)
You can see how the program first pokes B9 and then, after increasing the write pointer, the address to load on ECX. These three instructions effectively produce:
0x0804807c <+11>: b9 64 81 04 08 mov $0x8048164,%ecx
So, what we are going to do is to remove the inc and use the immediate addressing parameter to store our jump instruction. I want to have just one patch command because I prefer to have sequential bytes to patch even if I have to write some byte that is already there.
So, my patching sequence for the generator function will be:
90 c7 00 eb 0a
(remember the 90 NOP removes the INC so we start writing at the beginning of the generated instruction).
You see that I’m writing again C7 and 00. This 2 values are already there and we do not need to write them again but, as I said, this way I can just run 1 patch command. (Note that it is pretty easy to patch this with two non-consecutive writes just 2 bytes… it may even be a 1byte patch solution IDK 
Now, the last part is to obfuscate those bytes so we can patch the original file and then, when the de-obfuscate code is executed it will put our bytes in the right place in the generator function who will produce the code we wanted.
We already know that the key for the deobfuscator is 0x44 (I haven’t said this before, but I’m pretty sure you can figure this out yourself), so xoring our patch with the key (0x44) we get the final patch:
44 44 44 44 44
XOR
90 c7 00 eb 0a
--------------
d4 83 44 af 4e
The last piece of information we need is the offset in the file to write our patch. I’m pretty sure that, if you are reading this you already know how to calculate this… but, just in case.
First, let’s get the information for our .text section from the binary
$ readelf -S removeme.orig | grep ".text"
[ 1] .text PROGBITS 08048060 000060 000103 00 WAX 0 0 16
So, the .text segment is located at offset 60 in the file and it is mapped at 0x08048060 in memory. So, the file offset we are interest on is:
0x0804807c - 0x08048060 + 60 = 7c = 149
If you do not recall where does 0x0804807c comes from, just scroll up a bit and read again. As you can see, the offset in the file is 60 and the section address is 0x08048060, then we can just use the lower part of the address to know the file offset for any address. This is usually the case 
Now we can just patch the file with this data!
$ echo -ne "\xd4\x83\x44\xaf\x4e" | dd of=removeme.patch2 bs=1 seek=149 count=5 conv=notrunc
… and we are done.[/spoiler]