Jump to content

Welcome to Geeks to Go - Register now for FREE

Need help with your computer or device? Want to learn new tech skills? You're in the right place!
Geeks to Go is a friendly community of tech experts who can solve any problem you have. Just create a free account and post your question. Our volunteers will reply quickly and guide you through the steps. Don't let tech troubles stop you. Join Geeks to Go now and get the support you need!

How it Works Create Account
Photo

Decrypt this if you can :)


  • Please log in to reply

#1
MaverickSidewinder

MaverickSidewinder

    Member

  • Member
  • PipPipPip
  • 257 posts
Ok, i know you'll think i'm stupid for doing this, but i was fooling around with C++ and I came up with this code...

#include <iostream>
#include <string>
#include <cstdio>
#include <strings.h>

using namespace std;


 

int main(int nNumberofArgs, char* pszArgs[])

	{  
	   char word[256];
	   cout << "Please insert a word to encrypt: ";
	   cin >> word;
	   cout << "Ok so your word is " << word << endl;
	   cout << "Encoded it is like this: ";	
		
	   for(int i = 1; i <= word[i]; ++i)
		  {
			int b;
		b = word[i];
			cout << b; 
		  }
		  
	   cout << endl;	  
   
	}

What it does is it converts a word that you insert, to a number...

Is there a way to make a decrypter for this encrypter? Since, honestly I can't see how I encrypted it! (especially b=word[i])

I know it sounds like i ripped this source from someone...but i swear that i made it, i'm just too stupid to understand it :whistling:

:blink:

Edited by MaverickSidewinder, 28 June 2006 - 06:36 PM.

  • 0

Advertisements


#2
Swandog46

Swandog46

    Malware Expert

  • Member
  • PipPipPipPip
  • 1,026 posts
  • MVP
BAD! :blink: :whistling: There is a potential for an infinite loop and/or serious buffer overflow here.

You need to understand how characters are stored in memory to understand why this is so bad. A 'char' is an integer type. It stores a number in the range 0...255 or -127...127 (depending on whether it's unsigned or signed). But it's just a number. I could write:

char c = 1;
c++;
c *= 2;
// c now contains 4!

just like any other integer variable type. Now, second point: when you think you are storing letters in 'char' variables, you aren't. You're really just storing numbers. But when you use a function like putchar() or something to output a character to stdout, the function internally goes to the ASCII translation tables, looks up the symbol associated with the number stored in the 'char' variable, and spits that out. So the key point is this: the argument to a function like putchar() is just a number. I could do putchar(97); and something would be output to the screen (I think it's lowercase 'a').

Now, once we understand that, let's look back at the code.

This test:

i <= word[i];

actually checks to see whether the counter variable 'i' is less than or equal to the NUMBER stored in word[i]. That number is the ASCII representation of whatever word was entered earlier in the program. But it's still just a number. The loop will terminate only when i > word[i] for some i. So I could easily craft an attack on your program where I input word[i] = (i-1) for all i or something, and then i <= word[i] always, and this loop will never terminate. Or, alternatively, you would run right off the end of your 256-character 'word' buffer into memory you have not allocated. BAD! No guarantees what would happen.

By the way, the way this actually 'encodes' is just to spit out the ASCII representation of each character you have input. So if I wrote 'abc', the program would spit out the ASCII code for 'b' (98, I think), followed by the ASCII code for 'c' (99, I think). (check me on this). It starts at 'b' because you started i at 1 instead of 0. The reason it does this is because the overloaded cout << operator will output 'char' variables as their ASCII character equivalents (like putchar), but 'int' variables just as the pure numbers the ASCII characters correspond to. So the only reason this 'encodes' at all is because you have basically implicitly cast word[i] to an int by setting b=word[i]. If you just wrote word[i] to cout, you would do nothing more than write the input out to the output.

As a result, I could write a decoder for this just by repeated use of putchar()! The user gives me numbers, I putchar() them. voila! decoded. (I guess I would have to figure out how the digits break up into numbers, which would make it impossible. You would have to tell me where the digits break.)

Does this make sense? These are some pretty fundamental concepts about how characters are represented as numbers. Let me know if you have any questions. :help:
  • 0

#3
MaverickSidewinder

MaverickSidewinder

    Member

  • Topic Starter
  • Member
  • PipPipPip
  • 257 posts
Thanks for the reply :blink: I always thought that char's stored characters :whistling:


Anyway you were right...if i type "abc" it spits out 9899 :help:

I see what you are saying...so trying to decode this is very hard?

Edited by MaverickSidewinder, 29 June 2006 - 05:11 AM.

  • 0

#4
MaverickSidewinder

MaverickSidewinder

    Member

  • Topic Starter
  • Member
  • PipPipPip
  • 257 posts
Sorry for the double post, but I tried to make a decrypter, telling the user to insert only two digits at a time...

#include <iostream>
#include <string>
#include <cstdio>
#include <strings.h>

using namespace std;




int main(int nNumberofArgs, char* pszArgs[])

	{ 
	   char word[256];
	   cout << "What would you like to do? (E / D) ";
	   char choice;
	   cin >> choice;
	   switch(choice)
	   {
	   case 'E':
	   case 'e':
	   cout << "Please insert a word to encrypt: ";
	   cin >> word;
	   cout << "Ok so your word is " << word << endl;
	   cout << "Encoded it is like this: ";	
		
	   for(int i = 0; i <= word[i]; ++i)
		  {
			int b;
		b = word[i];
			cout << b;
		  }
		  
	   cout << endl;  
	   break;
	   case 'd':
	   case 'D':
	   int decrypt;
	   cout << "Please insert the first two digits of the number to decrypt: ";
	   cin >> decrypt;
	   cout << putchar(decrypt);
	   break;
	   default:
	   cout << "Please insert either a D or an E.";
	   cin.get();
	   cin.get();
	   break;
	   }
	   return 0;
	}

And it works, but most of the letters are more than 2 digits, f = 102...so that is a problem...any suggestions to improve it? :whistling:

Edited by MaverickSidewinder, 29 June 2006 - 06:10 AM.

  • 0

#5
Swandog46

Swandog46

    Malware Expert

  • Member
  • PipPipPipPip
  • 1,026 posts
  • MVP

Thanks for the reply :whistling: I always thought that char's stored characters

My pleasure -- I am glad to have cleared that up then, because that is a very fundamental point. Remember that internally, on the level of the CPU inside a computer, EVERYTHING is just numbers. Binary digits --- bits --- pushing around 0's and 1's. So on some level you need to be able to represent characters by numbers, for the computer to be able to deal with them. When C was created, ASCII was the standard encoding scheme for doing this (Unicode has by now all but replaced it). It just so happened that ASCII assigned numbers to exactly 256 different symbols. So a 'char' variable was designed to hold one of 256 different numbers (0...255) precisely to be able to store any ASCII code for a standard character. But internally, a char is still just a number.

Re: your decryptor --- that will do it! If you want to avoid the 2-digit problem, require everything be 3 digits, and if you want to input 97, just add a leading 0: 097 becomes 'a'.

If you want this to be a sensible encryptor/decryptor, you want to be able to feed something to the encryptor, feed the output immediately (without post-processing) to the decryptor, and get back the original input. So you'd have to change the encryptor slightly to output a leading zero to pad each encoded letter to three digits. There are printf() specifiers to do this, but I forget what they are off the top of my head. You can look it up. (I think printf("%03d", b); would do it)

Then change your decryptor not to accept any number of digits (via the cin >> call), but to accept exactly three digits on each pass (maybe just getchar() three times). Make sure to check your input to make sure you have gotten numbers! Otherwise spit out an error and exit. And please please please change the:

i <= word[i]

test to something like:

int i, i_max;

i_max = strlen(word) - 1;
for(i = 0; i <= i_max; ++i) {
[...]
}

This way you will never run off the end of the buffer. Note that I compute i_max before the start of the loop to avoid re-calling strlen() on each loop iteration, which would be grossly inefficient.
  • 0

#6
MaverickSidewinder

MaverickSidewinder

    Member

  • Topic Starter
  • Member
  • PipPipPip
  • 257 posts
Ok, I'll try that :whistling:

I was thinking of maybe concatenating a "-" in between every "encrypted" letter so decryption would be easier, what do you think about this?
  • 0

#7
Swandog46

Swandog46

    Malware Expert

  • Member
  • PipPipPipPip
  • 1,026 posts
  • MVP
that would be fine too. :whistling:
  • 0

#8
MaverickSidewinder

MaverickSidewinder

    Member

  • Topic Starter
  • Member
  • PipPipPip
  • 257 posts
I tried using what you told me:

#include <iostream>
#include <string>
#include <cstdio>
#include <strings.h>

using namespace std;




int main(int nNumberofArgs, char* pszArgs[])

	{  
	   char word[256];
	   cout << "Please insert a word to encrypt: ";
	   cin >> word;
	   cout << "Ok so your word is " << word << endl;
	   cout << "Encoded it is like this: ";	
		
	   int i, i_max;

	   i_max = strlen(word) - 1;
	   for(i = 0; i <= i_max; ++i) {
	   cout << i_max;
	   }
		  
	   cout << endl;	  
  
	}

But it doesn't really work :blink: , i type hello and it outputs 44444, i type yes and it outputs 222 ...

it counts the number of letters and outputs that number subracted by one as many times as the number of characters in the word.... :whistling:
  • 0

#9
MaverickSidewinder

MaverickSidewinder

    Member

  • Topic Starter
  • Member
  • PipPipPip
  • 257 posts
A little update...it adds a "-" after every letter...any suggestions for the decrypter? :whistling: Here is my try...

#include <iostream>
#include <string>
#include <cstdio>
#include <strings.h>

using namespace std;




int main(int nNumberofArgs, char* pszArgs[])

	{ 
	   char word[256];
	   cout << "What would you like to do? (E / D) ";
	   char choice;
	   cin >> choice;
	   switch(choice)
	   {
	   case 'E':
	   case 'e':
	   cout << "Please insert a word to encrypt: ";
	   cin >> word;
	   cout << "Ok so your word is " << word << endl;
	   cout << "Encoded it is like this: ";	
		
	   for(int i = 0; i <= word[i]; ++i)
		  {
			int b;
		b = word[i];
			cout << b << "-";
		  }
		  
	   cout << endl;  
	   break;
	   case 'd':
	   case 'D':
	   int decrypt;
	   cout << "Please insert sequence of numbers between the '-': ";
	   cin >> decrypt;
	   cout << putchar(decrypt) - decrypt;
	   break;
	   default:
	   cout << "Please insert either a D or an E.";
	   cin.get();
	   cin.get();
	   break;
	   }
	   return 0;
	}

On the putchar(); it had a problem, first if i didn't had "- decrypt" it would add the number, now i came up with another method:

	   int decrypt;
	   char letter[5];
	   char letter2[5];
	   for(;;)
		  {	
	   cout << "Please insert sequence of numbers between the '-': ";
	   cin >> decrypt;
	   letter[5] = putchar(decrypt);
	   strncpy(letter2, letter, 1);
	   cout << "\n";
		  }

It just displays the first character, and it loops so that you can add the encrypted letters more quickly..

Edited by MaverickSidewinder, 29 June 2006 - 08:58 AM.

  • 0

#10
Swandog46

Swandog46

    Malware Expert

  • Member
  • PipPipPipPip
  • 1,026 posts
  • MVP

I tried using what you told me: [...] But it doesn't really work, i type hello and it outputs 44444, i type yes and it outputs 222 ...

That's because you used this

for(i = 0; i <= i_max; ++i) {
cout << i_max;
}

when you really wanted this code:


for(i = 0; i <= i_max; ++i) {
cout << word[i];
}

In the former case all you are doing is continuously writing out copies of i_max! That is not what you want.

In your second post I really don't know what is going on. In your decrypt part, do you want the user to enter the entire set of numbers, separated by dashes? Or just one set of digits at a time? And I have no idea what this would do:

cout << putchar(decrypt) - decrypt;

My guess is that it would spit out a number representing the return value of putchar() minus decrypt. This is certainly not what you want. If you are only having the user enter one set of digits at a time, just call putchar() alone!

In your second example, you do realize that is an infinite loop right? How do you plan to get out of it? And why are you copying string buffers and then throwing away one of them (you do nothing with the letter2 buffer)?

If I get a chance later I will write this the correct way for you to see.
  • 0

#11
MaverickSidewinder

MaverickSidewinder

    Member

  • Topic Starter
  • Member
  • PipPipPip
  • 257 posts
Yeah i know that is an infinite loop :blink:

I set a control on the for loop saying that if a user enters a negative number it stops the loop :woot:

Here is an evolved version:

if(decrypt > 0) 
		 {
		 for(; decrypt > 0;)
		  { 
	   cout << "Please insert sequence of numbers between the '-': ";
	   cin >> decrypt;
	   
	   letter[5] = putchar(decrypt);
	   strncpy(letter2, letter, 1);
	   strcat(completeWord, letter2);   // adds the letters concatenating them one after the other...
		  }
	cout << "Ok, here is your decrypted word: " << completeWord;
	  }
	   else
		  {
		break;
		return 0;
	  }


but it doesn't work like it is supposed to :) , it spits out some wierd letters a not the ones i concatenate to the completeWord...

:whistling:

anyway i really appreciate your help swandog :help:
  • 0

#12
Swandog46

Swandog46

    Malware Expert

  • Member
  • PipPipPipPip
  • 1,026 posts
  • MVP
Sorry I haven't replied to this for a few days, been busy. Do you still want help with this MaverickSidewinder?
  • 0






Similar Topics

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

As Featured On:

Microsoft Yahoo BBC MSN PC Magazine Washington Post HP