经常我们在做外挂为了统易飞ERP的用户和密码。
查看用户表:
密码经过加密:
福州小兵提供了D7版本的加密和解密函数:
unit EnCode_New; interface uses SysUtils, Classes ,Dialogs ; const FNIL = '''(&.&!''%&$"''&)" ",&)$(%#$-$#$$" ' ; //NIL值 PS1 = '&''$%"# !./,-*+()' ; //密码符 FF1 = ' !"#$%&''()*+,-./'; //符号集 Function EnUser(s:String):string; //Function DeUser(s:String):string; Function Encode7(EnStr,s:string):string ; Function Decode7(EnStr,s:string):string ; implementation Function EnUser(s:String):string; var n,i,d:integer; begin Result := '' ; i := length(s) ; if i<=0 then exit ; Result := Copy(FNIL,(i-1)*2+1, 30-((i-1)*2)) ; for n:=i Downto 1 do begin //if n>1 then // Result := Copy(Result, 3, 30) ; //else // Result := Copy(Result, 1, 30) i := ((Ord(s[n])-32) Mod 16) ; d := ((Ord(s[n])-32) div 16)+1 ; Result := Result + CHR(32+d+1) + FF1[i+1] ; end; end; Function Encode7(EnStr,s:string):string ; var i,n1,n2:integer; FStr1,FStr2,FStr3:Char ; Fchar1:Char; begin Result := EnStr ; IF Length(s)=0 then Exit ; For i:=1 to Length(s) do begin case i of 1..4: begin FStr1 := s[i] ; //密码符 FStr2 := Result[i] ; //加密位置1 FStr3 := Result[32-4+i] ; //加密位置2 n1 := ((Ord(s[i])-32) mod 8) ; n2 := ((Ord(s[i])-32) div 16) ; Fchar1 := Chr(n2*16+32) ; //加密是什么类,数字或字母等 //这方法错误 正确的是 两个字符异或,再取其底阶字符+20H n2 := Ord(FStr2) xor Ord(FStr1) ; {Asm mov eax, n2 mov al, 0 mov n2, eax end; } n2 := (n2 AND $0F) + $20 ; //$20= 32 FStr2 := Chr(n2) ; FStr3 := Chr(Ord(Fchar1) + ((Ord(FStr3)+Ord(Fchar1)) Mod 16)) ; Result := COPY(Result,1,i-1)+FStr2+COPY(Result,i+1,32-i) ; Result := COPY(Result,1,32-4+i-1)+FStr3+COPY(Result,32-4+i+1,4-i) ; end; else begin FStr1 := s[i] ; //密码符 FStr2 := Result[i] ; //加密位置1 FStr3 := Result[i-4] ; //加密位置2 n1 := ((Ord(s[i])-32) mod 16) ; n2 := ((Ord(s[i])-32) div 16) ; Fchar1 := Chr(n2*16+32) ; //加密是什么类,数字或字母等 n2 := Ord(FStr2) xor Ord(FStr1) ; n2 := (n2 AND $0F) + $20 ; //$20= 32 FStr2 := Chr(n2) ; FStr3 := Chr(Ord(Fchar1) + ((Ord(FStr3)+Ord(Fchar1)) Mod 16)) ; Result := COPY(Result,1,i-1)+FStr2+COPY(Result,i+1,32-i) ; Result := COPY(Result,1,i-4-1)+FStr3+COPY(Result, i-4+1, 32-i+4) ; end; end; end; end; Function Decode7(EnStr,s:string):string ; var KeyLen,i,n1,n2:integer; FStr1,FStr2,FStr3,FStr4:Char ; Fchar1:Char; begin Result := '' ; IF EnStr='' then Exit ; if Length(s)<32 then //少于32位,错误 begin Result := 'ERROR!' ; EXIT; END ; IF s=EnStr then //NIL值 EXIT ; //检查密码有几位 KeyLen:=0 ; for i:=10 downto 1 do if s[i]<>EnStr[i] then begin KeyLen:=i ; Break ; end; if KeyLen=0 then Exit ; for i:=KeyLen Downto 1 do begin case i of 1..4: begin FStr1 := EnStr[i] ; //密码符 FStr2 := EnStr[32-4+i] ; //加密位置1 FStr3 := s[i] ; //加密位置2 FStr4 := s[32-4+i] ; //加密位置1 //n2*16+32 + (ord(FStr2) + (n2*16+32)) mod 16 ; n1 := ((Ord(s[i])-32) mod 8) ; n2 := ((Ord(s[i])-32) div 16) ; Fchar1 := Chr(n2*16+32) ; //加密是什么类,数字或字母等 //这方法错误 正确的是 两个字符异或,再取其底阶字符+20H n2 := Ord(FStr2) xor Ord(FStr1) ; n2 := (n2 AND $0F) + $20 ; //$20= 32 FStr2 := Chr(n2) ; FStr3 := Chr(Ord(Fchar1) + ((Ord(FStr3)+Ord(Fchar1)) Mod 16)) ; Result := COPY(Result,1,i-1)+FStr2+COPY(Result,i+1,32-i) ; Result := COPY(Result,1,32-4+i-1)+FStr3+COPY(Result,32-4+i+1,4-i) ; end; else begin end end; end; end; end.
模板写个C#版本加密类:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Utility { public class DCENCode { public string EnUser(char[] s) { string fnil = "'(&.&!'%&$\"'&)\" \",&)$(%#$-$#$$\" "; string FF1 = " !\"#$%&'()*+,-./"; int n, i, d; string Result; i = s.Length; Result = fnil.Substring((i - 1) * 2, 30 - (i - 1) * 2); for (n = i - 1; n >= 0; n--) { i = (Convert.ToInt32(s[n]) - 32) % 16; d = ((Convert.ToInt32(s[n]) - 32) / 16) + 1; Result = Result + Convert.ToChar(32 + d + 1) + FF1[i]; } return Result; } unsafe public string Encode7(string EnStr, char[] s) { int i, n1, n2; char FStr1, FStr2, FStr3, Fchar1; string Result = EnStr; for (i = 0; i < s.Length; i++) { if (i <= 3) { FStr1 = s[i]; FStr2 = Result[i]; FStr3 = Result[28 + i]; n1 = ((Convert.ToInt32(s[i]) - 32) % 8); n2 = ((Convert.ToInt32(s[i]) - 32) / 16); Fchar1 = Convert.ToChar(n2 * 16 + 32); n2 = Convert.ToInt32(FStr2) ^ Convert.ToInt32(FStr1); n2 = (n2 & 0x0F) + 0x20; FStr2 = Convert.ToChar(n2); FStr3 = Convert.ToChar(Convert.ToInt32(Fchar1) + ((Convert.ToInt32(FStr3) + Convert.ToInt32(Fchar1)) % 16)); Result = Result.Substring(0, i) + FStr2 + Result.Substring(i + 1, 31 - i); Result = Result.Substring(0, 28 + i) + FStr3 + Result.Substring(29 + i, 3 - i); } else { FStr1 = s[i]; FStr2 = Result[i]; FStr3 = Result[i - 4]; n1 = ((Convert.ToInt32(s[i]) - 32) % 16); n2 = ((Convert.ToInt32(s[i]) - 32) / 16); Fchar1 = Convert.ToChar(n2 * 16 + 32); n2 = Convert.ToInt32(FStr2) ^ Convert.ToInt32(FStr1); n2 = (n2 & 0x0F) + 0x20; FStr2 = Convert.ToChar(n2); FStr3 = Convert.ToChar(Convert.ToInt32(Fchar1) + ((Convert.ToInt32(FStr3) + Convert.ToInt32(Fchar1)) % 16)); Result = Result.Substring(0, i) + FStr2 + Result.Substring(i + 1, 31 - i); Result = Result.Substring(0, i - 4) + FStr3 + Result.Substring(i - 3, 35 - i); } } return Result; } } }
测试
结果与数据库中存取的密码:',5?9+"!$'&)" ",&)$(%#$-$#$$534$ 完全相同
BING GO