If you have the P2SH address (which will give you the HASH160 of the redeem script) and multiple private keys that you know are used in creation of that address, the recovery is a matter of simple brute force loop.
You can use any wallet that can create multi-sig addresses from keys but keep in mind that it is not flexible since they usually sort the public keys lexicographically that may not have been the way your script were created in first place.
In this case the most probable redeem script is a multi-sig one which means all you have to do is to test different combinations against the hash you have.
Redeem script is:
OP_m | pub_1 | pub_2 | ... | pub_n | OP_n | OP_CheckMultiSig
Here is a pseudocode of how the loop would look like:
loop m from 0 to n
select (1st pub) from [pub_1 to pub_n]
select (2nd pub) from [pub_1 to pub_n - (1st pub)]
...
set last pub
compute RIPEMD160 hash of SHA256 hash of script
compare with P2SH hash
print result
break
The loop for 3 public keys in total while allowing duplicates and accepting 0of3 scripts is like this:
int n = 3;
pubList = [pub1, pub2, pub3]
for (int m = 0; m <= n; m++)
{
for (int i = 0; i < pubList.Length; i++)
{
for (int j = 0; j < pubList.Length; j++)
{
for (int k = 0; k < pubList.Length; k++)
{
hash = ComputeHash(OP_m | pubList[i] | pubList[j] | pubList[k] | OP_n | 0xae);
if (hash == expected)
{
Print(m + i + j + k);
break;
}
}
}
}
}
This is 108 hashes that can be computed in a second or two.