Kłopotliwa konwersja c++/c#

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;
}
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#.

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;
}
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#.
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

0

Jakim programem go zdekompilowałeś?

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.

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