Kłopotliwa konwersja c++/c#

Odpowiedz Nowy wątek
2011-08-18 17:22
MateuszU
0

Witam, mam mały problem ponieważ mam pewne funkcjje kodujące i dekodujące w C++ lecz o wiele łatwiej pisze mi się programy w C# więc wczoraj cały dzień próbowałem przekonwertować lecz przy pewnych wynikach jest dobrze, a przy innych niektóre bajty są inne. W c# zamiast unsigned char* stosowałem tablice byte[] ale chciałbym wiedzieć jak według was powinno to wyglądać, mam nadzieje że sie czegoś nauczę.

void ShiftRight(unsigned char* ptr, unsigned int len, unsigned int shift) {
    if (shift == 0) return;
    for( unsigned int i = 1; i < len; ++i) {
        *ptr = (*ptr << shift) | (*(ptr+1) >> (8 - shift));
        ++ptr;
    }
    *ptr <<= shift;
}
// ...
void ShiftLeft(unsigned char* ptr, unsigned int len, unsigned int shift) {
    if (shift == 0) return;
    ptr +=len -1;
    for( unsigned int i = 1; i < len; ++i) {
        *ptr = (*ptr >> shift) | (*(ptr-1) << (8 - shift));
        --ptr;
    }
    *ptr >>= shift;
}
// ...
unsigned int ShiftBytes(unsigned char* buf, unsigned int arg_4, unsigned char* pkt, unsigned int arg_C, unsigned int arg_10) {
    unsigned int size_ = ((((arg_10 + arg_C) - 1) / 8) + (1 - (arg_C / 8)));
  unsigned char tmp1[20] ={ 0 };
    memcpy( tmp1, &pkt[arg_C /8], size_);
    unsigned int var_4 = (arg_10 + arg_C) & 0x7;
    if (var_4) tmp1[size_ - 1] &= 0xFF << (8 - var_4);
    arg_C &= 0x7;
    ShiftRight(tmp1, size_, arg_C);
    ShiftLeft(tmp1, size_ + 1, arg_4 & 0x7);
    if ((arg_4 & 0x7) > arg_C)
        ++size_;
    if(size_)
        for( unsigned int i =0; i < size_; ++i)
            buf[i+(arg_4/8)] |=tmp1[i];
    return arg_10 + arg_4;
}
// ...
void Encode8BytesTo11Bytes( unsigned char* outbuf, unsigned char* pktptr, unsigned int num_bytes, unsigned int* dec_dat) {
  unsigned char finale[2];
    finale[0] =(unsigned char)num_bytes;
    finale[0] ^= 0x3D;
    finale[1] =0xF8;
    for (int k = 0; k < 8; ++k)
        finale[1] ^= pktptr[k];
    finale[0] ^= finale[1];
  ShiftBytes( outbuf, 0x48, finale, 0x00, 0x10);
  unsigned int ring[4] ={ 0x000000000, 0x00000000, 0x00000000, 0x00000000 };
    unsigned short* cryptbuf =(unsigned short*)pktptr;
  ring[0] =((dec_dat[ 8] ^(cryptbuf[0])) *dec_dat[ 4]) %dec_dat[ 0];
  ring[1] =((dec_dat[ 9] ^(cryptbuf[1] ^(ring[0] &0xFFFF))) *dec_dat[ 5]) %dec_dat[ 1];
  ring[2] =((dec_dat[10] ^(cryptbuf[2] ^(ring[1] &0xFFFF))) *dec_dat[ 6]) %dec_dat[ 2];
  ring[3] =((dec_dat[11] ^(cryptbuf[3] ^(ring[2] &0xFFFF))) *dec_dat[ 7]) %dec_dat[ 3];
  unsigned int ring_backup[4] ={ ring[0], ring[1], ring[2], ring[3] };
  ring[2] =ring[2] ^dec_dat[10] ^(ring_backup[3] &0xFFFF);
  ring[1] =ring[1] ^dec_dat[ 9] ^(ring_backup[2] &0xFFFF);
  ring[0] =ring[0] ^dec_dat[ 8] ^(ring_backup[1] &0xFFFF);
  ShiftBytes( outbuf, 0x00, (unsigned char*)(&ring[0]), 0x00, 0x10);
  ShiftBytes( outbuf, 0x10, (unsigned char*)(&ring[0]), 0x16, 0x02);
  ShiftBytes( outbuf, 0x12, (unsigned char*)(&ring[1]), 0x00, 0x10);
  ShiftBytes( outbuf, 0x22, (unsigned char*)(&ring[1]), 0x16, 0x02);
  ShiftBytes( outbuf, 0x24, (unsigned char*)(&ring[2]), 0x00, 0x10);
  ShiftBytes( outbuf, 0x34, (unsigned char*)(&ring[2]), 0x16, 0x02);
  ShiftBytes( outbuf, 0x36, (unsigned char*)(&ring[3]), 0x00, 0x10);
  ShiftBytes( outbuf, 0x46, (unsigned char*)(&ring[3]), 0x16, 0x02);
}
// ...
int Decode11BytesTo8Bytes( unsigned char* outbuf, unsigned char* pktptr, unsigned int* dec_dat) {
  unsigned int ring[4] ={ 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
    ShiftBytes((unsigned char*)&ring[0], 0x00, pktptr, 0x00, 0x10);
    ShiftBytes((unsigned char*)&ring[0], 0x16, pktptr, 0x10, 0x02);
    ShiftBytes((unsigned char*)&ring[1], 0x00, pktptr, 0x12, 0x10);
    ShiftBytes((unsigned char*)&ring[1], 0x16, pktptr, 0x22, 0x02);
    ShiftBytes((unsigned char*)&ring[2], 0x00, pktptr, 0x24, 0x10);
    ShiftBytes((unsigned char*)&ring[2], 0x16, pktptr, 0x34, 0x02);
    ShiftBytes((unsigned char*)&ring[3], 0x00, pktptr, 0x36, 0x10);
    ShiftBytes((unsigned char*)&ring[3], 0x16, pktptr, 0x46, 0x02);
    ring[2] =ring[2] ^dec_dat[10] ^(ring[3] &0xFFFF);
    ring[1] =ring[1] ^dec_dat[ 9] ^(ring[2] &0xFFFF);
    ring[0] =ring[0] ^dec_dat[ 8] ^(ring[1] &0xFFFF);
    unsigned short* cryptbuf =(unsigned short*)outbuf;
    cryptbuf[0] =dec_dat[ 8] ^((ring[0] *dec_dat[ 4]) %dec_dat[0]);
    cryptbuf[1] =dec_dat[ 9] ^((ring[1] *dec_dat[ 5]) %dec_dat[1]) ^(ring[0] &0xFFFF);
    cryptbuf[2] =dec_dat[10] ^((ring[2] *dec_dat[ 6]) %dec_dat[2]) ^(ring[1] &0xFFFF);
    cryptbuf[3] =dec_dat[11] ^((ring[3] *dec_dat[ 7]) %dec_dat[3]) ^(ring[2] &0xFFFF);
  unsigned char finale[2] ={ 0x00, 0x00 };
    ShiftBytes(finale, 0, pktptr, 0x48, 0x10);
    finale[0] ^= finale[1];
    finale[0] ^= 0x3D;
    unsigned char m = 0xF8;
    for( int k = 0; k < 8; ++k)
        m ^= outbuf[k];
    if( m ==finale[1])
        return finale[0];
    return -1;
}

Pozostało 580 znaków

2011-08-18 17:30
msm
0

Zwykłe obliczenia (+, -, *, /) nie mają prawa się akurat niczym różnić w C#, C++ Pythonie i czymkolwiek innym.

Teoretycznie problem mógłby być w przepełnieniu (w C++ całkowicie dozwolone, w C# powoduje wyjątek (no właśnie - wyjątek a nie dziwne wyniki)). Możesz dla pewności umieścić cały kod w kontekście unchecked (ale nie sądzę żeby to coś zmieniło).

Sprawdź czy na pewno nie masz gdzieś jakiejś literówki - wystarczy zmienić 9 na 8 albo i na 1 i już błąd murowany.

Jeśli jesteś pewien że nie masz nigdzie literówki to wrzuć też kod C#.

edytowany 1x, ostatnio: msm, 2011-08-18 17:30

Pozostało 580 znaków

2011-08-18 18:41
MateuszU
0

Wyszło mi coś takiego ale wiem że jest źle, proszę o wypomnien ei mi błędów ;)

 public void ShiftRight(ref byte[] ptr, uint len, byte shift) {
    if (shift == 0) return;
           uint i = 1;
    for( i = 1; i < len; ++i) {
        ptr[i-1] = (byte)((ptr[i-1] << shift) | (ptr[i] >> (8 - shift)));
    }
    ptr[i] <<= shift;
}
// ...
void ShiftLeft(ref byte[] ptr, uint len, byte shift) {
    if (shift == 0) return;
    uint i = len -1;
    for( i = len -1; i > 1; --i) {
        ptr[i] = (byte)((ptr[i] >> shift) | (ptr[i-1] << (8 - shift)));
    }
    ptr[i] >>= shift;
}
// ...
public void memcpy(ref byte[] a1, ref uint[] a2, uint size, byte a2from)
{
    for(int i = 0; i < size; i++)
    {
        a1[i] = a1[i+a2from];
    }
}
 
public uint ShiftBytes(ref uint[] buf, uint arg_4,ref uint[] pkt, uint arg_C, uint arg_10, byte buffrom = 0, byte pktfrom = 0) {
    uint size_ = ((((arg_10 + arg_C) - 1) / 8) + (1 - (arg_C / 8)));
    byte[] tmp1 ={ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
    memcpy(ref tmp1, ref pkt, size_, (byte)(arg_C /8 + pktfrom));
    uint var_4 = (arg_10 + arg_C) & 0x7;
    if (var_4 > 0) tmp1[size_ - 1] &= (byte)((byte)0xFF << (byte)(8 - var_4));
    arg_C &= 0x7;
    ShiftRight(ref tmp1, size_, (byte)arg_C);
    ShiftLeft(ref tmp1, size_ + 1, (byte)(arg_4 & 0x7));
    if ((arg_4 & 0x7) > arg_C)
        ++size_;
    if(size_ > 0)
        for( uint i =0; i < size_; ++i)
            buf[i+(arg_4/8)+buffrom] |=tmp1[i];
    return arg_10 + arg_4;
}
// ...
void Encode8BytesTo11Bytes( ref uint[] outbuf, ref byte[] pktptr, uint num_bytes, ref uint[] dec_dat) {
    uint[] finale = {0,0};
    finale[0] =(byte)num_bytes;
    finale[0] ^= 0x3D;
    finale[1] =0xF8;
    for (int k = 0; k < 8; ++k)
        finale[1] ^= pktptr[k];
    finale[0] ^= finale[1];
  ShiftBytes(ref outbuf, 0x48,ref finale, 0x00, 0x10);
  uint[] ring ={ 0x000000000, 0x00000000, 0x00000000, 0x00000000 };
    byte[] cryptbuf = pktptr;
  ring[0] =(uint)(((dec_dat[ 8] ^(cryptbuf[0])) *dec_dat[ 4]) %dec_dat[ 0]);
  ring[1] =(uint)(((dec_dat[ 9] ^(cryptbuf[1] ^(ring[0] &0xFFFF))) *dec_dat[ 5]) %dec_dat[ 1]);
  ring[2] =(uint)(((dec_dat[10] ^(cryptbuf[2] ^(ring[1] &0xFFFF))) *dec_dat[ 6]) %dec_dat[ 2]);
  ring[3] =(uint)(((dec_dat[11] ^(cryptbuf[3] ^(ring[2] &0xFFFF))) *dec_dat[ 7]) %dec_dat[ 3]);
  uint[] ring_backup ={ ring[0], ring[1], ring[2], ring[3] };
  ring[2] =ring[2] ^dec_dat[10] ^(ring_backup[3] &0xFFFF);
  ring[1] =ring[1] ^dec_dat[ 9] ^(ring_backup[2] &0xFFFF);
  ring[0] =ring[0] ^dec_dat[ 8] ^(ring_backup[1] &0xFFFF);
  ShiftBytes(ref outbuf, (uint)0x00, ref ring, (uint)0x00, (uint)0x10);
  ShiftBytes(ref outbuf, 0x10, ref ring, 0x16, 0x02);
  ShiftBytes(ref outbuf, 0x12, ref ring, 0x00, 0x10, 0, 1);
  ShiftBytes(ref outbuf, 0x22, ref ring, 0x16, 0x02, 0, 1);
  ShiftBytes(ref outbuf, 0x24, ref ring, 0x00, 0x10, 0, 2);
  ShiftBytes(ref outbuf, 0x34, ref ring, 0x16, 0x02, 0, 2);
  ShiftBytes(ref outbuf, 0x36, ref ring, 0x00, 0x10, 0, 3);
  ShiftBytes(ref outbuf, 0x46, ref ring, 0x16, 0x02, 0, 3);
}
// ...
int Decode11BytesTo8Bytes(ref uint[] outbuf,ref uint[] pktptr,ref uint[] dec_dat) {
    uint[] ring ={ 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
    ShiftBytes(ref ring, 0x00,ref pktptr, 0x00, 0x10);
    ShiftBytes(ref ring, 0x16,ref pktptr, 0x10, 0x02);
    ShiftBytes(ref ring, 0x00,ref pktptr, 0x12, 0x10,1);
    ShiftBytes(ref ring, 0x16,ref pktptr, 0x22, 0x02,1);
    ShiftBytes(ref ring, 0x00,ref pktptr, 0x24, 0x10,2);
    ShiftBytes(ref ring, 0x16,ref pktptr, 0x34, 0x02,2);
    ShiftBytes(ref ring, 0x00,ref pktptr, 0x36, 0x10,3);
    ShiftBytes(ref ring, 0x16,ref pktptr, 0x46, 0x02,3);
    ring[2] =ring[2] ^dec_dat[10] ^(ring[3] &0xFFFF);
    ring[1] =ring[1] ^dec_dat[ 9] ^(ring[2] &0xFFFF);
    ring[0] =ring[0] ^dec_dat[ 8] ^(ring[1] &0xFFFF);
    uint[] cryptbuf =outbuf;
    cryptbuf[0] =dec_dat[ 8] ^((ring[0] *dec_dat[ 4]) %dec_dat[0]);
    cryptbuf[1] =dec_dat[ 9] ^((ring[1] *dec_dat[ 5]) %dec_dat[1]) ^(ring[0] &0xFFFF);
    cryptbuf[2] =dec_dat[10] ^((ring[2] *dec_dat[ 6]) %dec_dat[2]) ^(ring[1] &0xFFFF);
    cryptbuf[3] =dec_dat[11] ^((ring[3] *dec_dat[ 7]) %dec_dat[3]) ^(ring[2] &0xFFFF);
  uint[] finale ={ 0x00, 0x00 };
    ShiftBytes(ref finale, 0,ref pktptr, 0x48, 0x10);
    finale[0] ^= finale[1];
    finale[0] ^= 0x3D;
    byte m = 0xF8;
    for( int k = 0; k < 8; ++k)
        m ^= (byte)outbuf[k];
    if( m ==finale[1])
        return (int)finale[0];
    return -1;
}

Pozostało 580 znaków

2011-08-18 22:13
0
  1. nie musisz przekazywać tablic przez ref
  2. najpierw przerób program w C++ stopniowo tak, by nie korzystał ze wskaźników tylko z tablic. potem zostanie ci tylko zmiana nazw typów i niewielka zmiana składni na C#.
Ten program w C++ wygląda na zdekompilowany przez jakieś narzędzie a nie pisany przez człowieka (szczególnie się rzuca w oczy typowe dla disassemblerów domyślne nazewnictwo parametrów po lokalizacji na stosie (arg_C, arg_10)) - msm 2011-08-18 22:39
tak po prawdzie to C# posiada wskaźniki, i dla ćwiczenia w parę minut przerobiłem powyższy kod C++ w kompilujący się C# zachowując 95% treści bez żadnych zmian, ale dla przyzwoitości nie chciałem publicznie pokazywać takiej abominacji :-) - Azarien 2011-08-18 23:48

Pozostało 580 znaków

2011-08-18 22:59
MateuszU
0

Właśnie też się tego domyślałem ponieważ jest to kod deszyfracji pakietów pewnej gry. No trudno dziś w nocy pokombinuje, na studiach będzie łatwiej :D

Czyli zgadłem :> - msm 2011-08-18 23:00

Pozostało 580 znaków

2011-08-19 10:06
Aa
0

Jakim programem go zdekompilowałeś?

Pozostało 580 znaków

2011-08-19 18:13
MateuszU
0

Nie wiem, znalazłem to w internecie. Dzięki wszystkim za pomoc, sprawa się wyjaśniła. Niepotrzebnie zmienialem ShiftBytes tak aby przyjmowala uint zamiast bajtow, to uint powinienem zamienic na bajty przed wywolaniem.

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0