Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does `*p+++c&63` mean in C++?

Tags:

c

I'm a fan of the Hitman game, a stealth-action assassination game.

In the cinematic for the latest challenge, I spotted the following code-like snippet. I have no C++ experience and no C-tools installed on my system, so I tried copying it into a REPL here, but consistently got errors*

Here's my transcription of the code:

#include<stdio.h>
void main(int,char**a){for(char*p="25YZ[<TT];SR^2]W+%'C^,X-0?0&__V[!;TT];D+ #.A3,A+ 4C,$!_.",c=a[1][0];*p;putc(c=(*p+++c&63)+32,stdout));}

(Reformatted-for-readability later in this post).

So far as I can tell, this is meant to be a cypher ("take each character of cipher, pass it through a transformation, and print it out"), but I can neither get this to execute, nor understand it enough to translate it to a language that I know like Python: I have no idea what *p+++c&63 means. My guess is that it should be broken up as follows:

  • *p++ - take the next character of *p...
  • + - ...and add it(s integer representation) to...
  • c - ...the previously-set value of c (either from the previous iteration of the loop, or from initialization as c=a[1][0])...
  • &63 - ...do something? Looks like a bit-wise operator?
  • +32 - add 32 to the result

Additionally, the initial value of a seems to be the decryption key - but I've scoured the rest of the video, and can't find any hints as to what it's meant to be.

I tried to translate this to Python (iterating over all letters and numbers as the key) as follows:

import string

cipher = "25YZ[<TT];SR^2]W+%'C^,X-0?0&__V[!;TT];D+ #.A3,A+ 4C,$!_."

def printout(c):
  plaintext = ""
  for p in cipher:
    c = chr(ord(p) + ((ord(c) & 63)) + 32)
    plaintext += c
  print(plaintext)

for c in string.letters + string.digits:
  printout(c)

But each line of the resultant output is mostly garbage.

What am I missing? Have I mistranslated (C++) c=(*p+++c&63)+32 to (Python) c = chr(ord(p) + ((ord(c) & 63)) + 32) (within a for-loop, advancing p to the next character), or do I just need to cast my net wider for the decryption key?


Reformatted the original code a little for readability:

#include<stdio.h>
void main(int,char**a) {
  for(
    char*p="25YZ[<TT];SR^2]W+%'C^,X-0?0&__V[!;TT];D+ #.A3,A+ 4C,$!_.", 
      c=a[1][0];
    *p;
    putc(c=(*p+++c&63)+32,stdout)
  );}

* including, but not limited to, an error that main should return int, and that ISO C++11 does not allow conversion from string literal to 'char *'

like image 411
scubbo Avatar asked Mar 30 '19 21:03

scubbo


1 Answers

What does *p+++c&63 mean in C++?

  1. p++ Postfix increment. Increments pointer p to the next character; result is pointer value before increment.
  2. *p++ Indirection. Indirects through the pointer result of the expression 1. The result is the character that p originally pointed at, which is '2'.
  3. *p+++c Addition. Adds result of 2. and c. Same as *p++ + c
  4. *p+++c&63 Bitwise and. Left hand operand is the result of 3. and right hand operator is an integer literal.

With full parentheses and sensible spacing: (*(p++) + c) & 63


Here is a formatted, well-formed version that produces no warnings:

#include <stdio.h>

int main(int, char**a) {
    const char* p = "25YZ[<TT];SR^2]W+%'C^,X-O?O&__V[!;TT];D+ #.A3,A+ 4C,$!_.";
    for(char c = a[1][0];
        *p;
        putc(c=((*p++ + c) & 63) + 32, stdout));
}

The string "25YZ[<TT];SR^2]W+%'C^,X-O?O&__V[!;TT];D+ #.A3,A+ 4C,$!_." is probably encrypted text. The program decrypts it if given the key as an argument. The first character of the first argument is used as the key.

A program to brute force the key:


 #include <stdio.h>
 int main() {
     for (char i = 0; i < 127; i++) {
         const char* p = "25YZ[<TT];SR^2]W+%'C^,X-O?O&__V[!;TT];D+ #.A3,A+ 4C,$!_.";
         printf("%c: ", i);
         for(char c = i;
             *p;
             putc(c=((*p++ + c) & 63) + 32, stdout));
         putc('\n', stdout);
     }
 }
 

What am I missing?

  1. Order of operators 2. You're assuming that the key is alphanumeric.
like image 183
eerorika Avatar answered Nov 05 '22 14:11

eerorika