Ad
  • Custom User Avatar

    thank you for the upvote

  • Custom User Avatar

    there are no spoiler flag in comments of forks, so if you have something to tell involving the solutions, you should put that in the description of the fork, not here.

  • Custom User Avatar

    This comment is hidden because it contains spoiler information about the solution

  • Custom User Avatar

    I also was not able to find a solution shorter than 10 bytes. long double has 10 bytes which can be used for opcodes (it occupies 16 bytes in memory but 6 bytes are always 0).

  • Custom User Avatar

    it's the other way around. you start from the x64 assembly instructions you want to encode, then to their opcodes, then you concatenate these opcodes into bytes.

    let's see the bytes that make up the constant:

    const long double constant = 1.5249269223191329542e+59L;
    unsigned char bytes[sizeof constant];
    memcpy(bytes, &constant, sizeof constant);
    for (size_t i = 0; i < sizeof constant; i++)
        printf("%02hhx ", bytes[i]);
    

    output:

    f2 0f 59 c1 f2 0f 59 c2 c3 40 00 00 00 00 00 00 
    

    Let's disassemble those bytes (you can do it with an online tool, like this one):

    f2 0f 59 c1             mulsd  xmm0,xmm1
    f2 0f 59 c2             mulsd  xmm0,xmm2
    c3                      ret
    

    (the extra bytes is filler that will not be reached, since control will leave at the ret instruction)

    this assembly payload occupies 9 bytes of memory. this is too many for 64-bit = 8 bytes integers / double, this is why a long double was used (on Linux, long doubles occupy 16 bytes of memory). With this method, you can encode any payload - to see the constant that correspond to those bytes, you just have to reverse the process I showed in my first snippet: put the opcodes in an unsigned char[] array, memcpy() the bytes to your constant (which could be an int or long long if you need less bytes), and print it:

    const unsigned char bytes[16] = {0xf2, 0x0f, 0x59, 0xc1, 0xf2, 0x0f, 0x59, 0xc2, 0xc3, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
    long double constant;
    memcpy(&constant, bytes, sizeof bytes);
    // LDBL_DECIMAL_DIG ensures that it is printed to full precision and no significant digits are truncated
    printf("%.*Lg", LDBL_DECIMAL_DIG, constant);
    

    output:

    1.52492692231913295424e+59