Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9707

C# メモリ上の数値の改ざんを防ぐ

$
0
0

成果物

C#のコンソールテスト用です
https://github.com/Oinary/SecureValue/blob/master/Program.cs

1.やりたいこと

・改ざんされちゃマズい数値を守りたい!(ゲーム内のHPやお金など)
・ファイルだけではなくメモリ上の数値も保護したい。(今回はInt型とFloat型)

2.何を使えば出来るか

XOR(排他的論理和)で解決。
https://qiita.com/kuuso1/items/778acaa7011d98a3ff3a

簡単に言うと2進数で2つの数を演算したとき
片方がTrue(1)ならTrue。      0 xor 1 → 1
両方がTrue又はFalse(0)ならFalse。  0 xor 0 → 0

これって同じ値で演算しなおすと元の値に戻るんです。
1010 xor 0110→ 1100
1100 xor 0110→ 1010

科学の力ってすげぇ(てきとう

3.実装してみた

まずXORを使うのには、元の値とそれを合わせる値が必要。
C#でランダムな整数をもらってきます。(これはちゃんと保存しましょう)

Random.Next()
https://docs.microsoft.com/ja-jp/dotnet/api/system.random.next?view=netframework-4.8

あとは ^演算子で保存、復元すれば解決!

SecureInt.cs
privateintSeed;privateintValue;publicint_Value{get{returnValue^Seed;}set{Seed=newRandom().Next()//ランダムなIntValue=value^Seed;//あとはお好きに}}

3-1.そうは上手くいかなかった

Int型は何も問題なく実装できましたが…。
Float型ってXORを直接は使えない。(馬鹿には分からなかった。

3-2.じゃぁどう回避しようか

ヒントがここにあった…。
https://qiita.com/nia_tn1012/items/d26f0fc993895a09b30b

Floatで後ろ23ビットは仮数部と呼ばれる、我々が目にする数が格納されているところがあります。
例 2.345 → 2345 (小数点を無くした値になります)
その仮数部を隠せば良さげです。
※これはイメージです

Sample
floatF=1.55f;//得たfloatvarI=BitConverter.ToInt32(BitConverter.GetBytes(F),0);//これをbyte[]にして、Int型にさせるvarSignificandPart=I<<9;//左に9ビットシフトすると仮数部だけ残るvarSecureValue=SignificandPart^Seed;//あとは煮るなり焼くなり//戻すときはこの逆で

で出来上がりなのですが、まぁ操作多いんですよ。
なんかこう、もっとサクッとFloatをIntにできないんですかね…。

・・・あったわ

その参照記事の下に別の方法が書かれています。
ポインタを扱うこと がポイント♪で内部値をInt型で取得できます。

SecureFloat.cs
privateintSecValue;privateintSeed;publicunsafefloat_Value{get{varresult=SecValue^Seed;returnBitConverter.ToSingle(BitConverter.GetBytes(result),0);//戻すときは一度byte[]にしてからFloatに変換。}set{CalculatingSeed();intv=*((int*)&value);//&valueでvalueのポインタを取得、(int*)でInt型のポインタを格納、最初の*でそのポインタの値を指す。SecValue=v^Seed;//あとはお好きに}}

ポインタの使用は、本来はバグなど意図しない動作を防ぐために制限されています。
それを解除するため、unsafeを明示します。(VisualStudioの設定もお忘れずに)

これで守りたい値の保護方法が実装できそうです。

4.さいごに

不正の種類はいくつもあるので、それ相応の対応をしなければなりません。
が、あの手この手で不正してくるはずです。
実装するコストと見合っているかどうかも検討しないと、クオリティや製作時間に響いちゃいます。

僕みたいな初級の個人ゲームクリエイターならお遊び程度でいいんじゃないでしょうかね。

では初記事をご覧いただきありがとうございました。

※ってか一番大事なメモリエディタの画像なくね?


Viewing all articles
Browse latest Browse all 9707

Trending Articles